博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构——顺序表与链表
阅读量:4883 次
发布时间:2019-06-11

本文共 6666 字,大约阅读时间需要 22 分钟。

 

 

1.顺序表

我在学习完顺序表后一直对顺序表、数组、结构体数组这几个概念存在一些疑问,这里给出一些分析和看法。

顺序表:在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。

数组:把具有相同数据类型的若干变量按有序的形式组织起来,以便于程序处理,这些数据元素的集合就是数组。

从顺序表的定义来看,它和数组确实有很大的联系。首先,它是以数组的形式来保存的,其次,它和数组一样都是存储的元素物理地址相邻,具有很大的相似性。
但,仔细研究还是会发现它们的不同之处:
typedef struct Sqlist{    ElemType *slist;      /*存储空间的基地址,动态分配的一维数组*/    int length;           /*顺序表的当前长度*/    int listsize;         /*当前分配的存储空间*/} Sqlist;

顺序表是通过结构体来定义的,在结构体中有一个数组来保存顺序表所存储的数据,然后用定义的整形变量来确定数组中存储的有效数据的个数。而数组直接定义,简洁明了,很容易使用。这样看来数组比顺序表更加方便使用了。但是,数组也有它的缺陷它不能进行增,删等操作,而这些对顺序表来说就很简单了。

1 #include
2 #include
3 #define ERROR 0 4 #define OK 1 5 #define INIT_SIZE 5 /*初始分配的顺序表长度*/ 6 #define INCREM 5 /*溢出时,顺序表长度的增量*/ 7 typedef int ElemType; /*定义表元素的类型*/ 8 typedef struct Sqlist 9 { 10 ElemType *slist; /*存储空间的基地址*/ 11 int length; /*顺序表的当前长度*/ 12 int listsize; /*当前分配的存储空间*/ 13 } Sqlist; 14 15 int InitList_sq(Sqlist *L); /*线性表的初始化*/ 16 int CreateList_sq(Sqlist *L,int n); /* 构造一个长度为n顺序表 */ 17 int ListInsert_sq(Sqlist *L,int i,ElemType e);/*在表的第i个位置前插入一个元素e */ 18 int PrintList_sq(Sqlist *L); /*输出顺序表的元素*/ 19 int ListDelete_sq(Sqlist *L,int i); /*删除第i个元素*/ 20 int ListLocate(Sqlist *L,ElemType e); /*查找值为e的元素*/ 21 22 int InitList_sq(Sqlist *L) 23 { 24 L->slist=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType)); 25 if(!L->slist) 26 { 27 return ERROR; 28 } 29 L->length=0;///空表的长度为0 30 L->listsize=INIT_SIZE;///初始存储容量 31 return OK; 32 }/*InitList*/ 33 34 int CreateList_sq(Sqlist *L,int n) 35 { 36 ElemType e; 37 int i; 38 for(i=0; i
length; i++) 55 { 56 printf("%5d",L->slist[i-1]); 57 } 58 return OK; 59 }/*PrintList*/ 60 61 int ListInsert_sq(Sqlist *L,int i,ElemType e) 62 { 63 int k; 64 if(i<1||i>L->length+1)///i值不合法 65 { 66 return ERROR; 67 } 68 if(L->length>=L->listsize)///当前存储空间已满,增加分配 69 { 70 L->slist=(ElemType*)realloc(L->slist,(INIT_SIZE+INCREM)*sizeof(ElemType)); 71 if(!L->slist) 72 { 73 return ERROR; 74 } 75 L->listsize+=INCREM; 76 } 77 for(k=L->length-1; k>=i-1; k--)///元素后移 78 { 79 L->slist[k+1]= L->slist[k]; 80 } 81 L->slist[i-1]=e;///在第i个位置上插入元素e 82 L->length++;///表长加1 83 return OK; 84 }/*ListInsert*/ 85 86 /*在顺序表中删除第i个元素*/ 87 int ListDelete_sq(Sqlist *L,int i) 88 { 89 int p; 90 if(i<1||i>L->length)///i值不合法 91 { 92 return ERROR; 93 } 94 for(p=i-1; p
length-1; p++)///元素后移 95 { 96 L->slist[p]=L->slist[p+1]; 97 } 98 L->length--;///表长减1 99 return OK;100 }101 /*在顺序表中查找指定值元素,返回其序号*/102 int ListLocate(Sqlist *L,ElemType e)103 {104 int i;105 i=0;106 while((i<=L->length)&&(L->slist[i]!=e))107 {108 i++;109 }110 if(i<=L->length)111 {112 return i+1;113 }114 else115 {116 return -1;117 }118 }119 120 int main()121 {122 Sqlist sl;123 int n,m,k;124 printf("please input n:"); /*输入顺序表的元素个数*/125 scanf("%d",&n);126 if(n>0)127 {128 printf("\n1-Create Sqlist:\n");129 InitList_sq(&sl);130 CreateList_sq(&sl,n);131 printf("\n2-Print Sqlist:\n");132 PrintList_sq(&sl);133 printf("\nplease input insert location and data:(location,data)\n");134 scanf("%d,%d",&m,&k);135 ListInsert_sq(&sl,m,k);136 printf("\n3-Print Sqlist:\n");137 PrintList_sq(&sl);138 printf("\n");139 }140 else141 printf("ERROR");142 return 0;143 }

 

2.链表

顺序表在使用的时候有以下两个主要的缺点:

(1)插入和删除运算的时候必须移动大量(几乎一半)数据元素,效率低下。

(2)必须预先分配存储空间,造成空间利用率低,而且表的容量很难扩充。

为了克服顺序表的缺点,可以使用动态存储分配来存储线性表,也就是链式存储结构。

typedef struct LNode   /*线性表的单链表存储*/{    ElemType data;///数据域    struct LNode *next;///指针域} LNode,*LinkList;

在单链表中任何两个元素的存储位置之间没有固定的联系,每个元素的存储位置都包含在其直接前驱结点的信息中。

1 #include
2 #include
3 #define ERROR 0 4 #define OK 1 5 typedef int ElemType; /*定义表元素的类型*/ 6 typedef struct LNode /*线性表的单链表存储*/ 7 { 8 ElemType data;///数据域 9 struct LNode *next;///指针域 10 } LNode,*LinkList; 11 12 LinkList CreateList(int n); /*构造长度为n的链表*/ 13 void PrintList(LinkList L); /*输出带头结点单链表的所有元素*/ 14 int GetElem(LinkList L,int i,ElemType *e); /* 在第i个元素存在的情况下,替换为e*/ 15 16 LinkList CreateList(int n) 17 { 18 LNode *p,*q,*head; 19 int i; 20 head=(LinkList)malloc(sizeof(LNode)); 21 head->next=NULL;///头结点 22 p=head; 23 for(i=0; i
data); /*输入元素值*/ 28 q->next=NULL; /*结点指针域置空*/ 29 p->next=q; /*新结点连在表末尾*/ 30 p=q; 31 } 32 return head; 33 }/*CreateList*/ 34 35 void PrintList(LinkList L)///输出链表存储内容 36 { 37 LNode *p; 38 p=L->next; /*p指向单链表的第1个元素*/ 39 while(p!=NULL) 40 { 41 printf("%5d",p->data); 42 p=p->next; 43 } 44 }/*PrintList*/ 45 46 int GetElem(LinkList L,int i,ElemType *e)///获取链表第i位置上的元素 47 { 48 LNode *p; 49 int j=1; 50 p=L->next;///指向第一个节点 51 while(p&&j
next; 54 j++; 55 } 56 if(!p||j>i)///第i个元素不存在 57 { 58 return ERROR; 59 } 60 *e=p->data;///获取到第i个元素 61 return OK; 62 }/*GetElem*/ 63 64 int ListInsert_sq(LinkList L,int i,ElemType e)///向链表中第i个位置前插入元素 65 { 66 int j=0; 67 LinkList p=L,s; 68 while(p&&j
next; 71 j++; 72 } 73 if(!p||j>i-1) 74 { 75 return ERROR; 76 } 77 s=(LinkList)malloc(sizeof(struct LNode));///生成新结点 78 s->data=e;///插入 79 s->next=p->next; 80 p->next=s; 81 return OK; 82 } 83 int ListDelete(LinkList L,int i,ElemType *e)///删除链表第i个位置上的元素,并由e返回其值 84 { 85 int j=0; 86 LinkList p=L,q;///p初始化时指向头结点 87 while(p->next&&j
next; 90 j++; 91 } 92 if(!(p->next)||j>i-1) 93 { 94 return ERROR; 95 } 96 q=p->next;///q指向被删除结点 97 p->next=q->next; 98 *e=q->data; 99 free(q);100 return OK;101 }102 int main()103 {104 int n,i;105 ElemType e;106 LinkList L=NULL; /*定义指向单链表的指针*/107 printf("please input n:"); /*输入单链表的元素个数*/108 scanf("%d",&n);109 if(n>0)110 {111 printf("\n1-Create LinkList:\n");112 L=CreateList(n);113 printf("\n2-Print LinkList:\n");114 PrintList(L);115 printf("\n3-GetElem from LinkList:\n");116 printf("input i=");117 scanf("%d",&i);118 if(GetElem(L,i,&e))119 printf("No%i is %d",i,e);120 else121 printf("not exists");122 }123 else124 printf("ERROR");125 return 0;126 }

 

转载于:https://www.cnblogs.com/wkfvawl/p/9883872.html

你可能感兴趣的文章
JDBC的使用和SQL注入问题
查看>>
Sublime插件WakaTime使用
查看>>
vue-cli笔记
查看>>
xml转义字符在mybatis动态sql中的使用
查看>>
redis为什么设计成单线程并且还这么快?
查看>>
Lesson 45-46 Kids
查看>>
CocoaPods 1.0之前版本无法pod install和pod update! 更新后CocoaPods 1.1.1 Podfile新的写法....
查看>>
Java复习第一天——数组存储位置
查看>>
Java复习-基础类库
查看>>
Log4j rootLogger配置
查看>>
TCP、UDP、HTTP知识整理
查看>>
ORACLE 内置函数之GREATEST和LEAST
查看>>
C#语音朗读文本 — TTS的实现
查看>>
php常用易混淆概念
查看>>
本机搭建iis 开发环境
查看>>
js读取ognl表达式的内容
查看>>
layer弹出层全屏及关闭
查看>>
容器自动补全端口
查看>>
Linux下如何查看哪些进程占用的CPU内存资源最多
查看>>
RabbitMQ与Redis队列对比
查看>>