几种典型线性表的链式存储结构的比较
- 格式:ppt
- 大小:836.50 KB
- 文档页数:14
1、试比较挨次存储结构和链式存储结构的优缺点。
在什么状况下用挨次表比链表好?答:①挨次存储时,相邻数据元素的存放地址也相邻;内存中可用存储单元的地址必需是连续的。
优点:存储密度大( = 1),存储空间采用率高。
缺点:插入或删除元素时不便利。
②链式存储时,相邻数据元素可随便存放,但所占存储空间分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针. 优点:插入或删除元素时很便利,使用敏捷。
缺点:存储密度小(G),存储空间采用率低。
挨次表相宜于做查找这样的静态操作;链表宜于做插入,删除这样的动态操作。
若线性表的长度变化不大,且其主要操作是查找,则采纳挨次表;若线性表的长度变化较大,且其主要操作是插入、删除操作,则采纳链表。
顺序表和链表的比较:挨次表与链表的比较基于空间的比较•存储安排方式:挨次表的存储空间是静态安排的;链表的存储空间是动态安排的存储密度=结点数据本身所占的存储量/结点结构所占的存储总量:挨次表的存储密度=1;链表的存储密度V1基于时间的比较存取方式:挨次表可以随机存取,也可以挨次存取;链表是挨次存取的;插入/删除时移动元素个数; 挨次表平均需要移动近一半元素;链表不需要移动元素,只需要修改指针挨次表和链表的比较挨次表和链表各有短长。
在实际应用中毕竟选用哪一种存储结构呢?这要依据详细问题的要求和性质来打算。
储易于事先确定其大小时,为了节省 密 存储空间,宜采纳挨次表作为存储 度结构。
基I 存I 随机存取结构,对表中任一结点都I 挨次存取结构,链表中的结点,需II 于I 取I 可在O(I)时间内直接取得 I 从头指针起顺着链扫描才能取得。
I方 线性表的操作主要是进行查找,很 法少做插入和删除操作时,采纳挨次I 表做存储结构为宜。
在链表中的任何位置上进行插入和 删除,都只需要修改指针。
对于频 繁进行插入和删除的线性表,宜采 用链表做存储结构。
若表的插入和删除主要发生在表的首尾两端,则 采纳尾指针表示的I通常有以下几方面的考虑:! I 存I 为1。
在两种存储结构下实现线性表的创建,插入,删除,按值查找一、使用线性表的链式存储结构实现#include <stdio.h>#include <stdlib.h>typedef struct LNode{int data; //链表数据struct LNode* next; //链表指针}LNode,*LinkList;/*头插法-建立单链表*/LinkList HeadCreate(LinkList la){int num;la=(LinkList)malloc(sizeof(LNode)); //建立头结点la->next=NULL;scanf("%d",&num);while(num!=10){LNode *p=(LinkList)malloc(sizeof(LNode));p->data=num;p->next=la->next;la->next=p;scanf("%d",&num);}return la;}/*尾插法-建立单链表*/LinkList TailCreate(LinkList la){int num;la=(LinkList)malloc(sizeof(LNode));la->next=NULL;LinkList s,r=la;scanf("%d",&num);while(num!=10){s=(LinkList)malloc(sizeof(LNode));s->data=num;r->next=s;r=s;scanf("%d",num);}r->next=NULL;return la;}/*单链表遍历*/void TravelList(LinkList la){LinkList p=la->next;while(p!=NULL){printf("%d->",p->data);p=p->next;}printf("\n");}/*单链表的按位查找*/LinkList GetElem(LinkList la,int i){int j=1;LNode* p=la->next;if(i<1)return NULL;while(p && j<i){p=p->next;j++;}return p;}/*单链表的按值查找*/LinkList LocalElem(LinkList la,int e) {LNode* p=la->next;while(p!=NULL && p->data!=e)p=p->next;return p;}/*单链表插入操作*/bool InsertList(LinkList la,int i,int e){//在la链表中的i位置插入数值eint j=1;LinkList p=la,s;while(p && j<i){p=p->next;j++;}if(p==NULL)return false;if((s=(LinkList)malloc(sizeof(LNode)))==NULL)return false;s->data=e;s->next=p->next;p->next=s;return true;}/*单链表删除操作*/bool DeleteList(LinkList la,int i){int j=1;LinkList p=la,q;while(p && j<i) //p指向第i-1个元素{p=p->next;j++;}if(p==NULL || p->next==NULL) //表示不存在第i-1个和第i的元素return false;q=p->next;p->next=q->next;free(q);return true;}/*单链表的表长*/int LengthList(LinkList la)int nLen=0;LinkList p=la->next;while(p){p=p->next;nLen++;}return nLen;}/*单链表逆置*/LinkList Reserve(LinkList la){if(la==NULL || la->next==NULL)return la;LinkList p=la->next,q=p->next,r=q->next;la->next=NULL;p->next=NULL;while(r!=NULL){q->next=p;p=q;q=r;r=r->next;}q->next=p;la->next=q;return la;}int main(){LNode la;LinkList p;p=HeadCreate(&la); //头插法创建单链表TravelList(p);printf("%p\n",GetElem(p,1)); //获得第1个结点地址InsertList(p,2,10); //在链表的第2个位置插入元素10TravelList(p);DeleteList(p,3); //删除链表的第3个元素TravelList(p);printf("%d\n",LengthList(p)); //获得链表长度p=Reserve(p);TravelList(p);return 0;}//运行结果//5 6 12 7 8 14 9 3 2 5 14 10头插法创建链表//14->5->2->3->9->14->8->7->12->6->5-> 显示链表//00382490第一个结点的地址//14->10->5->2->3->9->14->8->7->12->6->5-> 插入元素值为10的结点//14->10->2->3->9->14->8->7->12->6->5-> 删除第三个结点//11 获//5->6->12->7->8->14->9->3->2->10->14-> 链表逆置//Press any key to continue二、使用线性表的顺序存储结构实现#include<stdio.h>#define MaxSize 50struct SqList{int data[MaxSize]; //存放顺序表的元素int length; //存放顺序表的长度};/*顺序表的插入操作*/bool InsertList(SqList&L,int i,int e){//在顺序表中第i个位置插入数值eint j;if(i<1 || i>L.length)return false;if(L.length>MaxSize)return false;for(j=L.length;j>=i;j--) //将第i个起得数据后移L.data[j]=L.data[j-1];L.data[j]=e;L.length++;return true;}/*顺序表的删除*/bool DeleteList(SqList&L,int i){//删除顺序表中第i个元素int j;if(i<1 || i>L.length)return false;for(j=i;j<L.length;j++)L.data[j-1]=L.data[j];L.length--;return true;}/*顺序表的按值查找*/int LocateElem(SqList&L,int e){for(int i=0;i<L.length;i++)if(L.data[i]==e)return i+1;return 0;}/*顺序表的输出*/void OutPutList(SqList&L){for(int i=0;i<L.length;i++)printf("%d ",L.data[i]);printf("\n");}int main(){SqList list;int A[5]={1,4,7,2,10};/*初始化顺序表*/for(int i=0;i<5;i++)list.data[i]=A[i];list.length=5;OutPutList(list);InsertList(list,3,12);OutPutList(list);DeleteList(list,3);OutPutList(list);printf("%d\n",LocateElem(list,10));return 0;}//运行结果//1 4 7 2 10 创建并输出顺序表//1 4 12 7 2 10 在3的位置插入值为12的元素//1 4 7 2 10 删除第三个元素//5 输出值为10的元素的位置//Press any key to continue上面是我用两种存储方式实现线性表的创建、插入、删除和按值查找的功能,还包含一些额外的功能,你可以自己根据我的代码改进,让代码更符合你的要求。
数据结构(⼆):线性表的链式存储结构1、为什么要使⽤链式存储结构?因为我们前⾯讲的线性表的顺序存储结构,他是有缺点的。
最⼤的缺点就是插⼊和删除时需要移动⼤量元素,这显然就需要耗费时间。
要解决这个问题,我们就需要分析⼀下为什么当插⼊和删除时,就要移动⼤量元素,因为相邻两元素的存储位置也具有相邻关系,它们在内存中的位置也是挨着的,中间没有空隙,当然就⽆法快速介⼊,⽽删除之后。
当中就会留出空隙,⾃然就需要弥补。
问题就出在这⾥。
为了解决这个问题,⾃然⽽然的就出现了链式存储结构。
2、线性表链式存储结构的特点:线性表的链式存储结构不考虑元素的存储位置,⽽是⽤⼀组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的,这就意味着,这些数据元素可以存在内存未被占⽤的任意位置。
顺序存储结构:只需要存储数据元素信息。
链式存储结构:除了要存储数据元素信息之外,还要存储⼀个指⽰其直接后继元素的存储地址。
3、关键词:数据域:存储数据元素信息的域。
指针域:存储直接后继位置的域。
指针或链:指针域中存储的信息。
结点(Node):指针域+数据域组成数据元素的存储映像。
头指针:链表中第⼀个结点的存储位置。
头节点:在单链表的第⼀个结点前附设⼀个结点,成为头结点。
头结点的数据域不可以存储任何信息,可以存储线性表的长度等附加信息,头结点的指针域存储指向第⼀个结点的指针。
4、单链表:定义:n个结点链成⼀个链表,即为线性表的链式存储结构,因此此链表的每个结点中只包含⼀个指针域,所以叫做单链表。
PS:线性链表的最后⼀个结点指针为“空”,通常⽤NILL或“^”符号表⽰。
头节点:在单链表的第⼀个结点前附设⼀个结点,成为头结点。
头结点的数据域不可以存储任何信息,可以存储线性表的长度等附加信息,头结点的指针域存储指向第⼀个结点的指针。
5、头结点与头指针的异同(1)头结点头结点是为了操作的统⼀和⽅便⽽设⽴的,放在第⼀个元素的结点之前,其数据域⼀般⽆意义(也可存放链表的长度)有了头结点,对第⼀元素结点前插⼊和删除第⼀结点,其操作就统⼀了头结点不⼀定是链表的必要素(2)头指针头指针式指向第⼀个结点的指针,若链表有头结点,则是指向头结点的指针。
⼏种常见的线性表存储结构1.线性表的的动态分配顺序存储结构1#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量2#define LISTINCREMENT 100 //线性表存储空间的分配增量3 typedef struct {4 ElemType *elem; //存储空间基址5int length; //当前长度6int size; //当前分配的存储容量7 }SqList; //动态分配 + 顺序存储结构2.线性表的单链表存储结构1 typedef struct LNode{ //结点类型2 ElemType data; //数据域3struct LNode *next; //指针域4 }*Link;5 typedef struct { //链表类型6 Link head, tail; //分别指向线性链表的头结点和最后⼀个结点7int len; //指⽰线性链表中数据元素的个数8 }LinkList;头指针:指⽰链表中第⼀个结点的存储位置(LNode *类型)头结点:单链表的第⼀个结点前附设⼀个结点(数据域可存长度 LNode类型)⾸元结点:第⼀个结点3.线性表的静态单链表存储结构1#define MAXSIZE 1000 //链表的最⼤长度2 typedef struct{3 ElemType data;4int cur;5 }Component, SLinkList[MAXSIZE];需要⽤户⾃⼰实现malloc和free函数,将所有未使⽤过的和被删除的结点⽤游标链成⼀个备⽤链表4.线性表的双向链表存储结构1 typedef struct DulNode{2 ElemType data;3struct DulNode *prior;4struct DulNode *next;5 }*Dulink;6 typedef struct { //链表类型7 Link head, tail; //分别指向线性链表的头结点和最后⼀个结点8int len; //指⽰线性链表中数据元素的个数9 }DulinkList;2015-06-27 21:21:29。