【转】基础知识系列2--线性表之链表

原文地址:http://www.cnblogs.com/mcgrady/p/3209419.html

 

上一篇我们总结完了顺序表,这一篇我们要总结的是线性表的链表,我想从以下几点进行总结。

1,为什么要使用链表? 
2,链表的存储结构? 
3,链表的常用操作代码实现?

 

1.为什么要使用链表

通过上一篇的学习,我们知道顺序表存在一些问题,主要有以下两个方面。

1,顺序表的长度是固定的,如果超出分配的长度就会造成溢出,如果存放的数据太少则会造成空间浪费。 
2,在插入元素和删除元素时(尤其不在尾部时),会移动大量的元素,造成性能和效率低下。

基于以上问题,使用链表可以很好地避免顺序表中出现的问题。这也是我们要使用链表的原因。

 

2.链表的存储结构

ds06

从上图可以看出,单链表中的每个结点都包含一个“数据域”和一个“指针域”。“数据域”中包含当前结点的数据,“指针域”包含下一节点的存储地址,头指针head是指向开始结点的,结束结点没有后继结点,所以结束结点的指针域为空,即null。

 

3.链表的常用操作及实现代码

链表常用的操作有:

1,插入结点到表头

思路:将head头指针的next指针给新增结点的next,然后将整个新增结点给head头指针的next。因此时间复杂度为O(1)。

示意图:

ds007 
2,插入结点到表尾

思路:插入方法与插入到表头一样,只不过多一个步骤就是通过head头指针循环找到终端结点。因此时间复杂度为O(n)。

示意图:

ds07 
3,插入结点(1≤i≤ListLength(L))

思路:插入方法与插入到表头一样,多循环查找当前结点的动作。因此时间复杂度为O(n)。

示意图:

ds08 
4,删除结点

思路:同插入结点一样,时间复杂度为O(n)。

示意图:

ds09 
5,查找结点

思路:与插入结点和删除结点方法类似,时间复杂度为O(n)。 
6,获取链表长度

思路:不像顺序表是连续存储的,获取表的长度非常容易。在链表中,数据不是连续存储的,因此需要循环遍历才能求得链表的长度,所以时间复杂度为O(n)。

 

代码实现:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define OK     0
  5 #define ERROR -1
  6 
  7 typedef int Status;  //函数结果状态
  8 typedef int ElemType; 
  9 typedef struct Node
 10 {
 11     ElemType data;
 12     struct Node *next;
 13 }Node;
 14 typedef struct Node *ChainList;
 15 Node *p;
 16 ChainList head;
 17 
 18 Status Init(ChainList *head)
 19 {
 20     *head = (ChainList)malloc(sizeof(Node));
 21 
 22     if(*head == NULL)
 23         return ERROR;
 24 
 25     (*head)->next = NULL;
 26     
 27     return OK;
 28 }
 29 //由于第i个结点的存储地址是存储在第i-1个结点的next中,因此,先让指针指向第i-1个结点,然后生成一个新结点插入
 30 Status Insert(ChainList head,int i,ElemType e)
 31 {
 32     int j=0;
 33     ChainList p,s;
 34     
 35     p = head;
 36     while(p!=NULL&&j<i-1)  //head内不保存数据
 37     {
 38         p = p->next;
 39         j++;
 40     }
 41 
 42     if(p==NULL||j>i-1)    //这个j>i-1代表着i不能输入小于1的非法值
 43         return ERROR;
 44 
 45     s = (ChainList)malloc(sizeof(Node));
 46     s->data = e;
 47     s->next = p->next;
 48     p->next = s;
 49     
 50     return OK;
 51 }
 52 
 53 Status Delete(ChainList head,int i)
 54 {
 55     int j=0;
 56     ElemType e;
 57     ChainList p,s;
 58     p=head;
 59 
 60     while(p!=NULL&&j<i-1)
 61     {
 62         p = p->next;
 63         j++;
 64     }
 65 
 66     if(p==NULL)
 67         return ERROR;
 68     else
 69     {
 70         s=p->next;
 71         p->next = s->next;
 72         e = s->data;
 73         free(s);
 74         return OK;
 75     }
 76 }
 77 
 78 int GetLength(ChainList head)
 79 {
 80     int i=0;
 81     ChainList p = head->next;
 82     
 83     while(p!=NULL)
 84     {
 85         p = p->next;
 86         i++;
 87     }
 88 
 89     return i;
 90 }
 91 
 92 Status GetDataByIndex(ChainList head,int i,ElemType *e)
 93 {
 94     int j=0;
 95     ChainList p,s;
 96 
 97     p=head->next;
 98 
 99     while(p!=NULL&&j<i-1)
100     {
101         p=p->next;
102         j++;
103     }
104 
105     if(p==NULL||j>i-1)
106         return ERROR;
107     *e = p->data;
108 
109     return OK;
110 }
111 
112 Status Display(ChainList head)
113 {
114     ChainList p=head->next;
115     printf("链表:");
116     while(p!=NULL)
117     {
118         printf("%d ",p->data);
119         p=p->next;
120     }
121     printf("\n");
122 
123     return OK;
124 }
125 
126 int main(void)
127 {
128     ChainList head;
129     ElemType e;
130     int j,k;
131 
132     printf("初始化\n");
133     if(Init(&head) == -1)
134         printf("Init Error\n");
135     printf("初始化后,链表长度:%d\n",GetLength(head));
136 
137     printf("插入10条数据\n");
138     srand((unsigned)time(NULL));
139     for(j=0;j<10;j++)
140     {
141         if(Insert(head,1,j) == -1)
142             printf("Insert Error\n");
143     }
144     Display(head);
145 
146     printf("删除第3条数据\n");
147     if(Delete(head,3) == -1)
148         printf("Delete Error\n");
149     printf("删除成功\n");
150     Display(head);
151 
152     printf("获取第5个结点的数据\n");
153     if(GetDataByIndex(head,5,&e) == -1)
154         printf("GetData Error\n");
155     printf("%d\n",e);
156 
157     return 0;
158 }

运行结果

posted @ 2015-11-13 16:37  L_free  阅读(302)  评论(0编辑  收藏  举报