首页 > 代码库 > 数据结构之线性表

数据结构之线性表

  线性表是最简单最常用的一种数据结构,在生活中各个方面都有应用。

  线性表的定义:线性表大多数情况下是除了第一个位置的数据元素只存在后继元素,最后一个位置的数据元素只存在前驱元素外,所有数据元素都存在前驱和后继的一个有限序列。举个简单的例子就是:字母表中除了 a 只存在后继 b,z 只存在前驱 y之外,剩余的所有字母全部都有前驱和后继。为什么是大多数情况下,是因为线性表的链式存储结构中除了单向链表,还有循环链表和双向链表。

  线性表的存储结构:顺序存储(数组实现,需要预先分配连续的内存空间)和链式存储(链表实现,不需要预先分配内存空间)

  在本篇文章利用C语言对线性表进行实现存储和相应算法。在线性表的链式存储中,我们可以定义结点的数据类型,结点包含两个域,分别为数据域指针域,数据域是用来存储要存储的数据元素的信息,而指针域就是存储下一个结点的地址,也就是指向下一个结点。码一下代码,方便以后回来看。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <math.h>
  4 
  5 typedef int ElemType;
  6 
  7 typedef struct node
  8 {
  9     ElemType data;
 10     struct node *next;
 11 }LNode,*LinkList;
 12 
 13 
 14 /*
 15     创建单链表头结点
 16 */
 17 LinkList createList(LinkList L)
 18 {
 19     L = (LinkList)malloc(sizeof(LNode));
 20     if(!L)
 21     {
 22         printf("内存申请失败!");
 23         exit(-1);
 24     }
 25     L->next = NULL;
 26     return L;
 27 }
 28 
 29 /*
 30     初始化单链表
 31 */
 32 void InitList(LinkList L)
 33 {
 34     int i=0,n;
 35     LinkList p,s;
 36     p=L;
 37 
 38     printf("请输入要建立的线性表长度:");
 39     scanf("%d",&n);
 40 
 41     for(i=0; i < n; i++)
 42     {
 43         s = (LinkList)malloc(sizeof(LNode));
 44         if(!s)
 45         {
 46             printf("内存分配失败!");
 47             exit(-1);
 48         }
 49 
 50         /*
 51             该函数实现的单向链表的数据元素是利用随机函数随机生成的,
 52             若想自己手动输入可把下面一句注释打开
 53         */
 54     //    scanf("%d",&s->data);
 55         s->data = http://www.mamicode.com/rand() % 100;
 56         s->next=NULL;
 57         p->next = s;
 58         p = s;
 59     }
 60 }
 61 
 62 /*
 63     遍历单链表
 64 */
 65 void TraverseList(LinkList L)
 66 {
 67     LinkList p;
 68 
 69     if(!L)
 70     {
 71         printf("线性表不存在!\n");
 72     }
 73     else
 74     {
 75         p = L->next;    //指向线性表的第一个元素
 76         while(p)
 77         {
 78             printf("%d -> ",p->data);
 79             p=p->next;
 80         }
 81             printf("\n");
 82     }
 83 }
 84 
 85 /*
 86     逆置单链表
 87 */
 88 void ReverseList(LinkList L)
 89 {
 90     LinkList p,q,s; //创建三个结点指针来进行线性表的逆置
 91     p = L->next;    //p指向第一个元素
 92     q=s=NULL;       //q/s开始置NULL
 93     while(p)        //p是当前要逆置的结点
 94     {
 95         q = p->next;    //q指向p的下一个结点,也就是要逆置的下一个结点
 96         p->next = s;    /* p为第一个结点:逆置后第一个结点变为最后一个结点,所以p的指针域为NULL
 97                             p不为第一个结点:p指向上一个结点
 98                         */
 99         s = p;          //逆置成功后,s指向当前逆置成功的结点
100         p = q;          //p指向要逆置的下一个结点
101     }
102     L->next = s;        //头指针L指向逆置成功后的第一个结点
103     TraverseList(L);
104 }
105 
106 /*
107     删除数据为偶数的节点
108 */
109 void DeleteEven(LinkList L)
110 {
111     LinkList p,s,q;
112     p = L;
113     while(p)
114     {
115         s = p;
116         while(s->next)
117         {
118             if(s->next->data % 2 == 0)
119             {
120                 q = s->next;
121                 s->next = q->next;
122                 free(q);
123             }
124             else
125             {
126                 s = s->next;
127             }
128         }
129         p = p->next;
130     }
131     TraverseList(L);
132 }
133 
134 /*
135     将单向链表排序
136 */
137 void SortList(LinkList L)
138 {
139     LinkList p,q;
140     int s;
141     for(p = L->next; p->next != NULL; p = p->next)
142     {
143         for(q = p->next; q != NULL; q = q->next)
144         {
145             if(p->data > q->data)
146             {
147                 s = p->data;
148                 p->data = http://www.mamicode.com/q->data;
149                 q->data =http://www.mamicode.com/ s;
150             }
151         }
152     }
153     TraverseList(L);
154 }
155 
156 /*
157     向有序表中插入数据
158 */
159 void InsertList(LinkList L,ElemType n)
160 {
161     LinkList p,s,q;
162     s = (LinkList)malloc(sizeof(LNode));
163     s->data =http://www.mamicode.com/ n;
164 
165     if(L->next == NULL)
166     {
167         s->next = NULL;
168         L->next = s;
169     }
170     else if(L)
171     {
172         for(q = L,p = L->next; p != NULL; p = p->next,q = q->next)
173         {
174             if(s->data <= p->data)
175             {
176                 s->next = p;
177                 q->next = s;
178                 break;
179             }
180             if(p->next == NULL)
181             {
182                 s->next = NULL;
183                 p->next = s;
184                 break;
185             }
186         }
187 
188     }
189     TraverseList(L);
190 
191 }
192 
193 /*
194     两个线性表的合并
195 */
196 void UnionList()
197 {
198     LinkList L1,L2,p,s;
199     int n,i = 0;
200 
201     printf("\n\n创建线性表L1:\n");
202     L1 = createList(L1);
203     InitList(L1);
204     SortList(L1);
205 
206     printf("创建线性表L2:\n");
207     L2 = createList(L2);
208     InitList(L2);
209     SortList(L2);
210 
211     printf("合并后线性表:\n");
212     p = L2->next;
213     while(p)
214     {
215         printf("第 %d 次插入: ",++i);
216         InsertList(L1,p->data);
217         p=p->next;
218     }
219 
220 }
221 
222 
223 int main()
224 {
225 
226     LinkList L;
227     ElemType n;
228     L = createList(L);
229     InitList(L);
230     TraverseList(L);
231     printf("逆置线性表:\n");
232     ReverseList(L);
233 
234     printf("删除数据为偶数的节点:\n");
235     DeleteEven(L);
236 
237     printf("排序后的线性表:\n");
238     SortList(L);
239 
240     printf("请输入要插入的数据:");
241     scanf("%d",&n);
242     printf("插入数据后的线性表:\n");
243     InsertList(L,n);
244 
245     UnionList();
246     return 0;
247 }

 

数据结构之线性表