浅谈数据结构之线性表链式存储(二)

  前面我们所讲的线性表的顺序存储结构,它是有优缺点,最大的缺点是插入与删除时需移动大量的元素,这显然需要耗费许多时间。这时,我们就引入线性表的链式存储结构,它的特点是:用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的。这就意味着,这些数据可以存在内存中未被占用的任意位置上,即当线性表进行插入与删除时就不需要移动大量的元素了,节约了时间。

  链式结构中,除了需要存储数据元素的信息外,还要存储它的后继元素的存储地址。我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。这两部分信息组成数据元素的存储映像,称为“结点”;n个结点链接成一个链表,我们称之为“单链表”。注意:链表的第一个结点的存储位置叫做头指针,整个链表的存取是从头指针开始的;同时我们规定链表的最后一个结点指针为“空”(通常用“NULL”表示)。有时,为了方便对链表进行操作,在单链表的第一个结点前附设一个结点,称为“头结点”,头结点的数据域可以不用存储任何信息,指针域存储指向第一个节点的指针。对于一个单链表来说,进行一系列插入、删除、初始化、置空等操作是非常重要的。下面,我们来看看单链表是如何进行插入与删除等操作,具体操作源代码如下所示:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3
  4 #define OK 1
  5 #define ERROR 0
  6 #define TRUE 1
  7 #define FALSE 0
  8
  9 #define MAXSIZE 100         /* 存储空间初始分配量 */
 10
 11 typedef int Status;         /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
 12 typedef int ElemType;       /* ElemType类型根据实际情况而定,这里假设为int */
 13
 14
 15 Status visit(ElemType c)
 16 {
 17     printf("%d ",c);
 18     return OK;
 19 }
 20
 21 typedef struct Node
 22 {
 23     ElemType data;
 24     struct Node *next;
 25 }Node;
 26 typedef struct Node *LinkList;          /* 定义LinkList */
 27
 28 /* 初始化顺序线性表 */
 29 Status InitList(LinkList *L)
 30 {
 31     *L=(LinkList)malloc(sizeof(Node));  /* 产生头结点,并使L指向此头结点 */
 32     if(!(*L))                           /* 存储分配失败 */
 33             return ERROR;
 34     (*L)->next=NULL;                    /* 指针域为空 */
 35
 36     return OK;
 37 }
 38
 39 /* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
 40 Status ClearList(LinkList *L)
 41 {
 42     LinkList p,q;
 43     p=(*L)->next;           /*  p指向第一个结点 */
 44     while(p)                /*  没到表尾 */
 45     {
 46         q=p->next;
 47         free(p);
 48         p=q;
 49     }
 50     (*L)->next=NULL;        /* 头结点指针域为空 */
 51     return OK;
 52 }
 53
 54 /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
 55 int ListLength(LinkList L)
 56 {
 57     int i=0;
 58     LinkList p=L->next;     /* p指向第一个结点 */
 59     while(p)
 60     {
 61         i++;
 62         p=p->next;
 63     }
 64     return i;
 65 }
 66
 67 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
 68 /* 操作结果:用e返回L中第i个数据元素的值 */
 69 Status GetElem(LinkList L,int i,ElemType *e)
 70 {
 71     int j;
 72     LinkList p;         /* 声明一结点p */
 73     p = L->next;        /* 让p指向链表L的第一个结点 */
 74     j = 1;              /*  j为计数器 */
 75     while (p && j<i)    /* p不为空或者计数器j还没有等于i时,循环继续 */
 76     {
 77         p = p->next;    /* 让p指向下一个结点 */
 78         ++j;
 79     }
 80     if ( !p || j>i )
 81         return ERROR;   /*  第i个元素不存在 */
 82     *e = p->data;       /*  取第i个元素的数据 */
 83     return OK;
 84 }
 85
 86 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
 87 /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
 88 Status ListInsert(LinkList *L,int i,ElemType e)
 89 {
 90     int j;
 91     LinkList p,s;
 92     p = *L;
 93     j = 1;
 94     while (p && j < i)     /* 寻找第i个结点 */
 95     {
 96         p = p->next;
 97         ++j;
 98     }
 99     if (!p || j > i)
100         return ERROR;      /* 第i个元素不存在 */
101     s = (LinkList)malloc(sizeof(Node));  /*  生成新结点(C语言标准函数) */
102     s->data = e;
103     s->next = p->next;     /* 将p的后继结点赋值给s的后继  */
104     p->next = s;           /* 将s赋值给p的后继 */
105     return OK;
106 }
107
108 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
109 /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
110 Status ListDelete(LinkList *L,int i,ElemType *e)
111 {
112     int j;
113     LinkList p,q;
114     p = *L;
115     j = 1;
116     while (p->next && j < i)    /* 遍历寻找第i个元素 */
117     {
118         p = p->next;
119         ++j;
120     }
121     if (!(p->next) || j > i)
122         return ERROR;           /* 第i个元素不存在 */
123     q = p->next;
124     p->next = q->next;          /* 将q的后继赋值给p的后继 */
125     *e = q->data;               /* 将q结点中的数据给e */
126     free(q);                    /* 让系统回收此结点,释放内存 */
127     return OK;
128 }
129
130 /* 初始条件:顺序线性表L已存在 */
131 /* 操作结果:依次对L的每个数据元素输出 */
132 Status ListTraverse(LinkList L)
133 {
134     LinkList p=L->next;
135     while(p)
136     {
137         visit(p->data);
138         p=p->next;
139     }
140     printf("\n");
141     return OK;
142 }
143
144 int main()
145 {
146     LinkList L;
147     ElemType e;
148     Status i;
149     int j,k;
150
151     i=InitList(&L);
152     printf("1.初始化L后:ListLength(L)=%d\n",ListLength(L));
153
154     for(j=1;j<=6;j++)
155             i=ListInsert(&L,1,j);
156     printf("2.在L的表头依次插入1~6后:L.data=");
157     ListTraverse(L);
158     printf("ListLength(L)=%d \n",ListLength(L));
159
160     i=ClearList(&L);
161     printf("3.清空L后:ListLength(L)=%d\n",ListLength(L));
162
163     for(j=1;j<=10;j++)
164             ListInsert(&L,j,j);
165     printf("4.在L的表尾依次插入1~10后:L.data=");
166     ListTraverse(L);
167
168     ListInsert(&L,1,0);
169     printf("5.在L的表头插入0后:L.data=");
170     ListTraverse(L);
171     printf("ListLength(L)=%d \n",ListLength(L));
172
173     j=5;
174     ListDelete(&L,j,&e);
175     printf("7.删除第%d个的元素值为:%d\n",j,e);
176     printf("依次输出L的元素:");
177     ListTraverse(L);
178
179     ListInsert(&L,5,4);
180     printf("8.插入第5个元素值后,依次输出L的值:L.data=");
181     ListTraverse(L);
182
183     return 0;
184 }
时间: 2024-11-09 01:47:29

浅谈数据结构之线性表链式存储(二)的相关文章

【C语言--数据结构】线性表链式存储结构

直接贴代码 头文件 #ifndef __LINKLIST_H__ #define __LINKLIST_H__ typedef void LinkList; typedef struct _tag_LinkListNode { LinkList* next; }LinkListNode; LinkList* LinkList_create(); void LinkList_Destroy(LinkList* pstList); void LinkList_Clear(LinkList* pstL

线性表链式存储结构的c语言实现

线性表链式存储结构的c语言实现的操作 <1>定义链式存储结构的结点. <2>初始化线性表 <3>判定是否为空 <4>清空列表 <5>返回L中数据元素个数 <6>用e返回L中第i个数据元素的值 <7>返回L中第1个与e满足关系的数据元素的位序,若没有则返回0 <8>在L中第i个位置之前插入新的数据元素e,L的长度加1 <9>删除L的第i个数据元素,并用e返回其值,L的长度减1 <10>依次

线性表链式存储的实现详解

本文原创,转载请注明:http://blog.csdn.net/j903829182/article/details/38173681 #include<stdio.h> #include<malloc.h> //线性表的链式存储和实现,带头点 #define true 1 #define false 0 typedef int DataType;//定义抽象数据类型 //节点的结构体 typedef struct Node{ DataType data;//节点的数据域 stru

线性表链式存储的基本操作

线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任意元素.线性表链式存储结构特点是用一组任意的存储单元存储数据元素,为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储本身信息外,还要存储指示其直接后继的信息(即直接后继的存储位置).这两部分信息称为数据元素ai的存储映像,称为结点(node).它包括两个域,其中存储数据信息的称为数据域,存储直接后继存储位置的域称为指针域. 1.线性表的单链表存储结构 typ

线性表链式存储设计与实现 - API实现

基本概念 链式存储定义 为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息. 表头结点 链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息 数据结点 链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息 尾结点 链表中的最后一个数据结点,其下一元素指针为空,表示无后继. 链表技术领域推演 链表链式存储_api实现分析 在C语言中可以用结构体来定义链表中的指针域 链表中的表头结点也可以用结构体实现

数据结构 - 线性表链式存储结构

链式存储 链式存储 :用一组任意的存储单元存储线性表中的数据元素.用这种方法存储的线性表简称线性链表. 存储链表中结点的一组任意的存储单元可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的. 链表中结点的逻辑顺序和物理顺序不一定相同.(即不要求逻辑上相邻的元素在物理位置上也相邻) 为了正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其直接后继结点的地址(或位置),称为指针(pointer)或链(link),这两部分组成了数据元素ai的存储映像 链表是通过每个结点

数据结构与算法——线性表链式存储(单链表)

今天总结单链表的实现. 什么是链表? 就是采去链式存储结构的线性表,所谓链式存储就好比火车的车厢一样,一节一节的连接起来,成为一个线性表.这种方式采用动态存储分配方式,即程序在运行时根据实际需要申请内存空间,不需要时将内存空间释放掉. 链表用一组任意的存储单元存放线性表中的各个元素,这组存储单元可以是连续的,也可以是不连续的. 什么是单链表? 单链表简单理解就是单向的,就像火车一样.如果将火车头与火车为连接在一块,就构成了循环链表. 链表的结构:链表采用节点结构,这个节点分为两部分,一部分存储数

数据结构(一)线性表链式存储实现

(一)前提 在前面的线性表顺序存储结构,最大的缺点是插入和删除需要移动大量的元素,需要耗费较多的时间.原因:在相邻两个元素的存储位置也具有邻居关系,他们在内存中的位置是紧挨着的,中间没有间隙,当然无法快速插入和删除.为了解决这个为题,出现了链式存储结构 (二)链式线性表两种结构(带有头结点和不带头结点) 不带头结点: 空链表: 带有头结点: 空链表: (三)头结点和头指针的区别 头指针: 1.头指针是指向第一个结点的指针,若是链表中只有头结点,则是指向头结点的指针 2.头指针具有标识作用,所以常

浅谈数据结构之线性表顺序存储(一)

 首先,数据结构是由某一数据元素集合及该集合中所有数据元素之间的关系组成.具体来说,数据结构应当包含三方面的内容:(1).数据的逻辑结构:(2).数据的存储结构:(3).对数据所施加的操作.而数据的存储结构形式有两种:顺序存储与链式存储.在这里,先谈一谈线性表的顺序存储. 线性表:零个或多个数据元素的有限序列.第一,它是一个序列,也就是说,元素之间是有顺序的:第二,它是有限的,即元素个数是有限的.而线性表的顺序存储结构,说白了,就是在内存中找块地,通过占位的形式把一定的内存空间给占了,然后把相同