数据结构之单链表

148 阅读2分钟

1,内存存储方式

19532021-8c43f08686b7a567.webp

2,基本介绍

1、链表是以节点的方式来存储,是链式存储
2、每个节点包含 data 域, next 域:指向下一个节点.
3、如图:发现链表的各个节点不一定是连续存储.
4、链表分带头节点的链表和没有头节点的链表,根据实际的需求来确定

3,带头节点的链表

头结点只是用来记录开始位置,一般不存数据,只记录next。

代码实现

package LinkedList;

public class SingleLinkedListDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SingleLinkedList s = new SingleLinkedList();
		HeroNode node1 = new HeroNode(1, "老大", 12);
		HeroNode node2 = new HeroNode(2, "老二", 12);
		HeroNode node3 = new HeroNode(3, "老三", 12);
		s.add(node1);
		s.add(node2);
		s.add(node3);
		s.list();
		
		s.delete(4);//找不到该元素
		s.delete(2);
		s.list();
	}

}

//定义节点
class HeroNode {
	public int no;
	public String name;
	public int age;
	HeroNode next;

	// 构造器
	public HeroNode(int no, String name, int age) {
		this.no = no;
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "HeroNode [no=" + no + ", name=" + name + ", age=" + age + "]";
	}

}

//定义链表
class SingleLinkedList {

	private HeroNode head = new HeroNode(0, null, 0);

	// 返回头结点
	public HeroNode getHead() {
		return head;
	}

	// 尾部添加元素
	public void add(HeroNode hNode) {
		HeroNode temp = head;
		while (temp.next != null) {
			temp = temp.next;
		}
		temp.next = hNode;
	}
	//如果想在中间插入可以使用下面这种方式
        //hNode.next = temp.next;
        //temp.next = hNode;
	

	// 遍历链表
	public void list() {
		HeroNode temp = head;
		while (temp.next != null) {
			System.out.println(temp.next);
			temp = temp.next;
		}
	}

	// 删除
	// 1. head 不能动,因此我们需要一个temp辅助节点找到待删除节点的前一个节点
	// 2. 说明我们在比较时,是temp.next.no 和 需要删除的节点的no比较
	public void delete(int no) {
		HeroNode temp = head;
		Boolean flag = false;
		while (true) {
			// 为空返回
			if (temp.next == null)
				break;
			if (temp.next.no == no) {
				flag = true;
				break;
			}
			temp = temp.next;
		}
		
		if (flag) {
			temp.next = temp.next.next;
		} else {
			System.out.println("找不到该元素");
		}
	}//delete

}

输出结果

Snipaste_2021-10-31_16-32-16.png

几道练习题

1,单链表反转

// 单链表反转,遍历单链表,依次塞到一个新节点的最前端
	public static void reversetList(HeroNode head) {

		HeroNode cur = head.next;
		HeroNode next = null;
		HeroNode reversehead = new HeroNode(0, "", 0);

		while (cur != null) {
			next = cur.next;
			cur.next = reversehead.next;
			reversehead.next = cur;
			cur = next;
		}
		head.next = reversehead.next;
	}

2,返回倒数第k个元素

// 返回倒数第k个元素
	public static HeroNode findLastIndexNode(HeroNode head, int index) {

		HeroNode temp = head;
		int size = 0;
                //算总数
		while (temp.next != null) {
			size++;
			temp = temp.next;
		}
                
                //越界直接返回
		if (index <= 0 || index > size) {
			return null;
		}
                
                //找到所要的元素
		HeroNode temp1 = head;
		for (int i = 0; i <= size - index; i++) {
			temp1 = temp1.next;
		}

		return temp1;
	}// findLastIndexNode

3,单链表反向遍历

//反向遍历,利用栈先进后出的特性,存入取出即可
	public static void reversePrint(HeroNode head) {
		//创建栈
		Stack<HeroNode> stack = new Stack<HeroNode>();
		
		//压入栈
		HeroNode cur = head.next;
		while(cur != null) {
			stack.push(cur);
			cur = cur.next;
		}
		//出栈
		while(stack.size() > 0) {
			System.out.println(stack.pop());
		}
		
	}