首页 > 编程知识 正文

链式存储结构可以指定位置存储吗,链式存储结构的特点是利用

时间:2023-05-06 02:29:51 阅读:159558 作者:2875

线性表的链式存储结构:

为什么采用链存储结构这一数据结构?

顺序存储结构会极大地影响效率,因为插入或删除元素时会涉及许多元素的移动。

为此,为了弥补顺序存储结构在效率上的问题,引入了链式存储结构。

定义链存储结构:

1 .存储数据要素信息的域称为数据域,存储直接后继位置的域称为指针域。

2 .指针字段中存储的信息称为指针或链。 将由这2个信息构成的数据要素称为存储映像,称为节点(Node )。

3.n个节点链接到一个链表是线性表(a1、a2、a3、an )的链式存储结构。

4 .此链表中的每个节点只包含一个指针字段,因此称为单链表。

#节点Node应如下图所示。

单链表的结构如下图所示。

链表的基本概念:链表中第一个节点的存储位置称为头指针,链表中的第一个节点称为头节点。

头节点分为虚拟头节点和真头节点:

虚拟头节点:第一个节点不包含数据,只是指向下一个节点的地址。 如下图红色节点所示:

虽然没有什么用,但在实际工程中发现添加表头代码变得简单了,维护性也变好了,所以只是帮助代码简化,不包含信息,只是直接指向后续地址; 指向路线图中的第0个元素

真实头节点:第一个节点也用于存储数据。 如下图所示。

数据节点:表示链表数据元素的节点。 ()数据元素、地址);

尾部节点:链表中的最后一个数据节点。 地址信息为空。

头指针与头结点的异同

头指针

头指针是指向链表中第一个节点的指针,如果链表中有头节点,则是指向头节点的指针。

因为头指针具有标识的作用,所以头指针经常冠以链表的名称(指针变量的名称)。

不管链表是否为空,头指针都不为空。

头指针是链表的必需元素。

头节点

头节点是为了统一操作和方便而设立的,放在第一个元素的节点之前,其数据域一般没有意义。 但是,它也可以用于存储链表的长度。

如果有头节点,则对在第一要素节点之前插入节点和删除第一节点的操作与其他节点统一。

头节点不一定是链表的必需元素。

链结构的代码实现:在解释了基本概念之后,我们来看看链结构的具体方法是如何实现的。 在本文中,我们将使用虚拟头节点。

链表中插入元素分为两种方式:插头法和插尾法。

头插入法:头插入法是将新节点总是插入头部,以开头节点的链表为例,链表的头部指针为Head,追加节点p

那么

p-next=Head-next;

头下一个=p;

如果是没有站在最前面的链表的话,应对措施是

p-next=Head;

头=p;

尾插法:然后,尾插法是通过在链表的末尾插入新节点,

for(t=head ); 叔下; t=t-next; //结束时t指向末尾的节点

p-next=NULL; //插入

t-next=p;

具体的代码实现:

@ overridepublicvoidadd (intindex,e ) if ) index0||indexsize ) thrownewillegalargumentexception '插入角点标记错误!' ); }noden=newnode(e,null ); if(index==0) )//头加上n.next=head.next; 头儿. next=n; if(size==0) {rear=n; }elseif(index==size ) ) /末尾为rear.next=n; rear=rear.next; (else(/通常为Node p=head; for(intI=0; iindex; I ) {p=p.next; (}n.next=p.next; p.next=n; (}size; }如何从链表中删除元素:

元素的删除图像如下图所示。

链表第I个数据删除节点的算法思路:

节点p指向链表中的第一个节点,宣言初始化j=1;

在j1的情况下,遍历链表,将p的指针向后移动,继续指向下一个节点,j递增1;

如果p到链表的末尾为空,则表示第I个元素不存在。

否则,将想删除的节点p-next代入q;

删除单链表标准语句p-next=q-next;

将q节点的数据代入e,作为返回

释放q节点。

代码实现如下。

publiceremove(intindex ) if ) index0||index=size ) thrownewillegalargumentexception '删除角标记是非法的!' ); (}E res=null; if(index==0) (/头删除Node p=head.next; res=p.data; head.next=p.next; p.next=null; p=null; I

f(size==1){rear=head;}}else if(index==size-1){//尾删Node p=head;res=rear.data;while(p.next!=rear){p=p.next;}p.next=null;rear=p;}else{//一般删除Node p=head;for(int i=0;i<index;i++){p=p.next;}Node del=p.next;res=del.data;p.next=del.next;del.next=null;del=null;}size--;return res;}

以上就是链式存储结构的基本概念,下面附全代码供参考:

package com.lfz.链表;import com.lfz.线性表.*;public class LinkedList<E> implements List<E> {/** * 单向链表的结点类 * */private class Node{E data;//数据域Node next;//指针域public Node(){this(null,null);}public Node(E data,Node next){this.data=data;this.next=next;}@Overridepublic String toString() {return data.toString();}}private Node head;//指向虚拟头结点的头指针private Node rear;//指向尾结点的尾指针private int size;//记录元素的个数public LinkedList(){head=new Node();rear=head;size=0;}public LinkedList(E[] arr){this();for (E e : arr) {addLast(e);}}@Overridepublic int getSize() {return size;}@Overridepublic boolean isEmpty() {return size==0&&head.next==null;}@Overridepublic void add(int index, E e) {if(index<0||index>size){throw new IllegalArgumentException("插入角标非法!");}Node n=new Node(e,null);if(index==0){//头插n.next=head.next;head.next=n;if(size==0){rear=n;}}else if(index==size){//尾插rear.next=n;rear=rear.next;}else{Node p=head;for(int i=0;i<index;i++){p=p.next;}n.next=p.next;p.next=n;}size++;}@Overridepublic void addFirst(E e) {add(0,e);}@Overridepublic void addLast(E e) {add(size,e);}@Overridepublic E get(int index) {if(index<0||index>=size){throw new IllegalArgumentException("查找角标非法!");}if(index==0){return head.next.data;}else if(index==size-1){return rear.data;}else{Node p=head;for(int i=0;i<=index;i++){p=p.next;}return p.data;}}@Overridepublic E getFirst() {return get(0);}@Overridepublic E getLast() {return get(size-1);}@Overridepublic void set(int index, E e) {if(index<0||index>=size){throw new IllegalArgumentException("修改角标非法!");}if(index==0){head.next.data=e;}else if(index==size-1){rear.data=e;}else{Node p=head;for(int i=0;i<=index;i++){p=p.next;}p.data=e;}}@Overridepublic boolean contains(E e) {return find(e)!=-1;}@Overridepublic int find(E e) {int index=-1;if(isEmpty()){return index;}Node p=head;while(p.next!=null){p=p.next;index++;if(p.data==e){return index;}}return -1;}@Overridepublic E remove(int index) {if(index<0||index>=size){throw new IllegalArgumentException("删除角标非法!");}E res=null;if(index==0){//头删Node p=head.next;res=p.data;head.next=p.next;p.next=null;p=null;if(size==1){rear=head;}}else if(index==size-1){//尾删Node p=head;res=rear.data;while(p.next!=rear){p=p.next;}p.next=null;rear=p;}else{Node p=head;for(int i=0;i<index;i++){p=p.next;}Node del=p.next;res=del.data;p.next=del.next;del.next=null;del=null;}size--;return res;}@Overridepublic E removeFirst() {return remove(0);}@Overridepublic E removeLast() {return remove(size-1);}@Overridepublic void removeElement(E e) {int index=find(e);if(index==-1){throw new IllegalArgumentException("元素不存在");}remove(index);}@Overridepublic void clear() {head.next=null;rear=head;size=0;}@Overridepublic String toString() {StringBuilder sb=new StringBuilder();sb.append("LinkedList:size="+getSize()+"n");if(isEmpty()){sb.append("[]");}else{sb.append("[");Node p=head;while(p.next!=null){p=p.next;if(p==rear){sb.append(p.data+"]");}else{sb.append(p.data+",");}}}return sb.toString();}@SuppressWarnings("unchecked")@Overridepublic boolean equals(Object obj) {if(obj == null) {return false;}if(obj == this) {return true;}if(obj instanceof LinkedList) {LinkedList<E> list = (LinkedList<E>) obj;if(getSize() == list.getSize()) {for(int i=1;i<getSize();i++) {if(get(i) != list.get(i)) {return false;}}return true;}}return false;}}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。