大话数据结构(六)——链式存储
线性表链式存储结构定义
线性表的链式存储结构的特点:用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。
为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身信息以外,还需要存储一个指示其直接后继的信息。
我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称作指针或者链。这两部分信息组成数据元素ai的存储映像,称为结点(node)。
n个结点(ai的存储映像),称为结点(Node)。
n个结点(ai的存储映像)链结成一个链表,即线性表(a1,a2,a3,……an)的链式存储结构,因为此链表的每个结点只包含一个指针域,所以叫单链表。
链表中第一个结点的存储位置叫做头指针。
头指针与头结点的异同
头指针
头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。
头指针具有标识作用,所以常用头指针冠以链表的名字。
无论链表是否为空,头指针均不为空,头指针是链表的必要元素。
头结点
头结点是为了操作的统一和方便而设立的,放在第一个元素的结点之前,其数据域一般无意义。
有了头结点,对在第一元素结点前插入结点和删除第一结点,其操作与其他结点的统一了。
头结点不一定是链表必须要素。
用java语言描述链式存储结构
class Node {//用对象描述存储结构 Object data; //数据域 Node next;//指针域 public Node(Object data2) { this.data = data2; } }
单链表的读取
算法思路:
1、声明一个指针p指向链表的第一个结点,初始化j从1开始
2、当j<i时,就遍历链表,让p指针向后移动一位,不断地指向下一个结点,j++;
3、若到链表末尾p为空,则说明第i个结点不存在
4、否则查找成功,返回结点p的数据
public Node index(int index){ if(index==0){ //头一个结点下标为0 current=head; return current; //删除后链表为空 }else{ current=head; for(int i=0;i<index-1;i++){ current=current.next; //因为current.next赋值给了current,所以要设置为index-1 } } return current; }
单链表的插入
算法思路:
1、声明一个指针p指向链表的第一个结点,初始化j从1开始
2、当j<i时,就遍历链表,让p指针向后移动一位,不断地指向下一个结点,j++;
3、若到链表末尾p为空,则说明第i个结点不存在
4、否则查找成功,在系统中生成一个空节点s
5、将数据元素e赋值给s->data
6、单链表的插入标准语句,s->next = p->next,p->next=s;
7、返回成功
//方法:向链表中添加数据 public void add(Object data) { //判断链表为空的时候 if (head == null) {//如果头结点为空,说明这个链表还没有创建,那就把新的结点赋给头结点 head = new Node(data); current = head; number++; } else { //创建新的结点,放在当前节点的后面(把新的结点和链表进行关联) current.next = new Node(data); //把链表的当前索引向后移动一位 current = current.next; //此步操作完成之后,current结点指向新添加的那个结点 number++; } }
单链表的删除
算法思路:
1、声明一个指针p指向链表的第一个结点,初始化j从1开始
2、当j<i时,就遍历链表,让p指针向后移动一位,不断地指向下一个结点,j++;
3、若到链表末尾p为空,则说明第i个结点不存在
4、否则,查找成功,将欲删除的结点p->next赋给q
5、单链表的删除标准语句p->next=q->next
6、将q结点中的数据赋给e,作为返回
7、释放q结点
8、返回成功
public void delete(int data){ index(data); if(data==0){ head=current.next; }else{ current.next=current.next.next; number--; } } //需要一个定位的方法 用于删除方法 当输入索引后先找到索引结点的前一个结点,把前一个结点的next指向后一个的后一个 //也可以用双指针,时间复杂度降低 public Node index(int index){ if(index==0){ //头一个结点下标为0 current=head; return current; //删除后链表为空 }else{ current=head; for(int i=0;i<index-1;i++){ current=current.next; //因为current.next赋值给了current,所以要设置为index-1 } } return current; }