单链表简单介绍
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
单链表的实现
实现单链表的添加、更新、删除、遍历、获取链表长度等方法
首先定义一个节点类HereNode,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
class HeroNode { public int no; public String name; public String nickname; public HeroNode next;
public HeroNode(int no, String name, String nickname) { this.no = no; this.name = name; this.nickname = nickname; }
public HeroNode(int no, String name, String nickname, HeroNode next) { this.no = no; this.name = name; this.nickname = nickname; this.next = next; }
@Override public String toString() { return "HeroNode{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '\'' + '}'; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
class SingleLinkedList {
private HeroNode head = new HeroNode(0, "", "");
public void add(HeroNode heroNode) { HeroNode temp = head; while (temp.next != null) { temp = temp.next; if (temp.no==heroNode.no) { System.out.println("这个排名:"+heroNode.no+"已经存在了"); return; } } temp.next = heroNode; }
public void addById(HeroNode heroNode) { HeroNode temp = head;
while (temp.next != null) { if (heroNode.no == temp.next.no) { System.out.printf("已存在该排名:%d\n", heroNode.no); return; } else if (heroNode.no < temp.next.no) { break; } temp = temp.next; } heroNode.next = temp.next; temp.next = heroNode; }
public void update(HeroNode newHeroNode) { HeroNode temp = head.next; if (temp == null) { System.out.println("链表为空~"); return; } boolean flag = false; while (temp != null) { if (temp.no == newHeroNode.no) { flag = true; break; } temp = temp.next; } if (flag) { temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; } else { System.out.println("没有找到排名为" + newHeroNode.no + "的英雄"); } }
public void remove(int no) { HeroNode temp = head; boolean flag = false; while (temp.next != null) { if (temp.next.no == no) { flag = true; break; } temp = temp.next; } if (flag) { temp.next = temp.next.next; }else { System.out.println("没有排名为"+ no +"的英雄!"); } }
public void list() { if (head.next == null) { System.out.println("链表为空"); return; } HeroNode temp = head.next; while (temp != null) { System.out.println(temp); temp = temp.next; } }
public int getLength(){ if (head.next==null) { return 0; } HeroNode temp = head; int i = 0; while(temp.next!=null){ i++; temp = temp.next; } return i; }
|
单链表的面试题
查找单链表中倒数第k个节点 【新浪面试题】
思路:
- 单链表的长度-k+1,就是链表正序的位置,例如:链表长度为10,k为9,则正序位置为2,也就是第二个结点
- 前提是 长度 - k >=0, 且 k不能小于等于0。
1 2 3 4 5 6 7 8 9 10 11 12
| public HeroNode selectByK(int k){ if(k <= 0 && k > getLength()){ throw new RuntimeException("K值:"+k+",不合法"); } HeroNode temp = head; int index = getLength - k + 1; for(int i = 0; i < index; i++){ temp = temp.next; } return temp; }
|
单链表的反转 【腾讯面试题】
思路:
定义一个新的链表,将旧链表(要反转的链表)的元素遍历,依次插入头结点的后面,并连接好头节点后面的原结点。最后新链表就是反转后的链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
public static SingleLinkedList reverse(SingleLinkedList oldList) { if (oldList.getLength() == 0) { return null; } if (oldList.getLength() == 1) { return oldList; } SingleLinkedList newList = new SingleLinkedList(); HeroNode temp = oldList.head.next; HeroNode temp2 = null; while (temp != null) { temp2 = temp; temp = temp.next; temp2.next = null;
temp2.next = newList.head.next; newList.head.next = temp2; } return newList; }
|
逆序打印单向链表 【百度面试题】
思路1:使用栈这种数据结构进行存储
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
public void reversePrint() { HeroNode temp = head.next; if (temp == null) { return; } Stack<HeroNode> stack = new Stack<>(); while (temp != null) { stack.push(temp); temp = temp.next; }
while (stack.size() > 0) { System.out.println(stack.pop()); } }
|
思路2:使用递归的方式
1 2 3 4 5 6 7 8 9 10 11 12
| public void reversePrint2(HeroNode startNode){ if (startNode == null) { return; } if (startNode.next != null) { reversePrint2(startNode.next); } if (startNode != head) { System.out.println(startNode); } }
|