线性表:
线性表(亦作顺序表)是最基本、最简单、也是最常用的一种数据结构。
线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。
线性表的逻辑结构简单,便于实现和操作。
在实际应用中,线性表都是以栈、队列、字符串等特殊线性表的形式来使用的。
线性结构的基本特征为:
1.集合中必存在唯一的一个“第一元素”;
2.集合中必存在唯一的一个 “最后元素” ;
3.除最后一个元素之外,均有 唯一的后继(后件);
4.除第一个元素之外,均有 唯一的前驱(前件)。
链表:linked list
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的
每个数据项都被包含在“链结点”(Link)中。
链结点是一个类的对象,这类可叫做Link。链表中有许多类似的链结点,每个Link中都中包含有一个对下一个链结点引用的字段next。
链表对象本身保存了一个指向第一个链结点的引用first。(若没有first,则无法定位)
链表不能像数组那样(利用下标)直接访问到数据项,而需要用数据间的关系来定位,即访问链结点所引用的下一个链结点,而后再下一个,直至访问到需要的数据
单链表:
以“结点的序列”表示线性表 称作线性链表(单链表)
是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。(这组存储单元既可以是连续的,也可以是不连续的)
链结点的结构:
┌────┬────┐
│data│next│
└────┴────┘
存放结点值的数据域data;存放结点的引用 的指针域(链域)next
链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。
每个结点只有一个链域的链表称为单链表(Single Linked List) , 一个方向, 只有后继结节的引用
/* * 单链表:头插法 后进先出 * 将链表的左边称为链头,右边称为链尾。 * 头插法建单链表是将链表右端看成固定的,链表不断向左延伸而得到的。 * 头插法最先得到的是尾结点 */ public class SingleLinkedList<T> { private Link<T> first; //首结点 public SingleLinkedList() { } public boolean isEmpty() { return first == null; } public void insertFirst(T data) {// 插入 到 链头 Link<T> newLink = new Link<T>(data); newLink.next = first; //新结点的next指向上一结点 first = newLink; } public Link<T> deleteFirst() {//删除 链头 Link<T> temp = first; first = first.next; //变更首结点,为下一结点 return temp; } public Link<T> find(T t) { Link<T> find = first; while (find != null) { if (!find.data.equals(t)) { find = find.next; } else { break; } } return find; } public Link<T> delete(T t) { Link<T> p = first; Link<T> q = first; while (!p.data.equals(t)) { if (p.next == null) {//表示到链尾还没找到 return null; } else { q = p; p = p.next; } } q.next = p.next; return p; } public void displayList() {//遍历 System.out.println("List (first-->last):"); Link<T> current = first; while (current != null) { current.displayLink(); current = current.next; } } class Link<T> {//链结点 T data; //数据域 Link<T> next; //后继指针,结点 链域 Link(T data) { this.data = data; } void displayLink() { System.out.println("the data is " + data.toString()); } } public static void main(String[] args) { SingleLinkedList<Integer> list = new SingleLinkedList<Integer>(); list.insertFirst(33); list.insertFirst(78); list.insertFirst(24); list.insertFirst(56); list.displayList(); list.deleteFirst(); list.displayList(); System.out.println("find:" + list.find(56)); System.out.println("find:" + list.find(33)); System.out.println("delete find:" + list.delete(99)); System.out.println("delete find:" + list.delete(78)); list.displayList(); } }
打印
List (first-->last): the data is 56 the data is 24 the data is 78 the data is 33 List (first-->last): the data is 24 the data is 78 the data is 33 find:null find:[email protected] delete find:null delete find:[email protected] List (first-->last): the data is 24 the data is 33
/* * 单链表:尾插法 先进先出 * 若将链表的左端固定,链表不断向右延伸,这种建立链表的方法称为尾插法。 * 尾插法建立链表时,头指针固定不动,故必须设立一个尾部的指针,向链表右边延伸, * 尾插法最先得到的是头结点。 */ public class SingleLinkedList2<T> { private Link<T> head; //首结点 private Link<T> rear; //尾部指针 public SingleLinkedList2() { } public boolean isEmpty() { return head == null; } public void insertLast(T data) {//在链尾 插入 Link<T> newLink = new Link<T>(data); if (rear != null) { rear.next = newLink; } else { head = newLink; head.next = rear; } rear = newLink; //下次插入时,从rear处插入 } public Link<T> deleteLast() {//删除 链尾 Link<T> p = head; Link<T> q = head; while (p.next != null) {// p的下一个结点不为空,q等于当前的p(即q是上一个,p是下一个) 循环结束时,q等于链尾倒数第二个 q = p; p = p.next; } //delete q.next = null; return p; } public Link<T> find(T t) { Link<T> find = head; while (find != null) { if (!find.data.equals(t)) { find = find.next; } else { break; } } return find; } public Link<T> delete(T t) { Link<T> p = head; Link<T> q = head; while (!p.data.equals(t)) { if (p.next == null) {//表示到链尾还没找到 return null; } else { q = p; p = p.next; } } q.next = p.next; return p; } public void displayList() {//遍历 System.out.println("List (first-->last):"); Link<T> current = head; while (current != null) { current.displayLink(); current = current.next; } } class Link<T> {//链结点 T data; //数据域 Link<T> next; //后继指针,结点 链域 Link(T data) { this.data = data; } void displayLink() { System.out.println("the data is " + data.toString()); } } public static void main(String[] args) { SingleLinkedList2<Integer> list = new SingleLinkedList2<Integer>(); list.insertLast(33); list.insertLast(78); list.insertLast(24); list.insertLast(56); list.displayList(); list.deleteLast(); list.displayList(); System.out.println("find:" + list.find(56)); System.out.println("find:" + list.find(33)); System.out.println("delete find:" + list.delete(99)); System.out.println("delete find:" + list.delete(78)); list.displayList(); } }
打印
List (first-->last): the data is 33 the data is 78 the data is 24 the data is 56 List (first-->last): the data is 33 the data is 78 the data is 24 find:null find:[email protected] delete find:null delete find:[email protected] List (first-->last): the data is 33 the data is 24