一、实验目的
1.了解顺序表的结构特点及有关概念
2.掌握顺序表建立、插入、删除的基本操作算法
3.了解单链表的结构特点、描述方法及有关概念
4.掌握单链表建立、插入、删除的基本操作算法
二、顺序表
在高级语言(如C语言)环境下:数组具有随机存取的特性,因此,借助数组来描述顺序表。除了用数组来存储线性表的元素之外,顺序表还应该有表示线性表的长度属性,所以用结构类型来定义顺序表类型。采用静态分配的顺序存储结构来表示。
包含的基本操作有:
1.建立顺序表: Status creatlist(sequenlist *L)
2.插入一个元素:Status insert(sequenlist *L,elemtype x,int i)
3.删除一个元素: Status dellist(sequenlist *L,int i)
4.输出顺序表: void printout(sequenlist *L)(辅助函数)
顺序线性表的插入
1
2
3在线性表 L= (a1,…a i-1,ai, ai+1,…,an) 中的第i(1≦i≦n)个位置上插入一个新结点e,使其成为线性表: L=(a1,…a i-1,e,ai,ai+1,…,an)
算法思想
(1) 进行合法性检查,1<=i<=n+1;
(2) 检查线性表是否已满;
(3) 将第n个至第i个元素逐一向后移动一个单元;
(4) 在第i个位置处插入新元素;
(5) 将表的长度加1.
顺序线性表的删除
1
2
3在线性表 L=(a1,…a i-1,ai, ai+1,…,an) 中删除结点ai(1≦i≦n),使其成为线性表: L= (a1,…ai-1,ai+1,…,an)
实现步骤
(1)进行合法性检查,1<=i<=n;
(2)将线性表L中的第i+1个至第n个结点依此向前移动一个位置。
(3) 线性表长度减1。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129#include "stdio.h" #include "malloc.h" #define maxsize 1024 typedef char elemtype; typedef struct { elemtype list[maxsize]; int length; }sequenlist; //创建顺序表 void creatlist(sequenlist *L); //插入元素 int insert(sequenlist *L,elemtype x,int i); //删除元素 int dellist(sequenlist *L,int i); //输出顺序表 void printout(sequenlist *L); //创建顺序表 void creatlist(sequenlist *L) { int n,i; char tmp; printf("请输入数据的个数:"); scanf("%d",&n); for(i = 0; i < n; i ++) { printf("list[%d] = ",i); fflush(stdin);//清空输入缓冲区,通常是为了确保不影响后面 的数据的读入 scanf("%c",&tmp); L -> list[i] = tmp; } L -> length = n-1; } //插入元素 int insert(sequenlist *L,elemtype x,int i) { int j; if(L -> length == maxsize - 1)//判满 { printf("overflow"); return 0; } else if((i < 0) || (i > L -> length)) //判插入位置是否合法 { printf("error,please input the right 'i'n"); return 0; } else { for(j = L-> length; j >= i; j --) L -> list[j+1] = L -> list[j]; L -> list[i] = x; L -> length = L -> length + 1; } return 1; } //删除元素 int dellist(sequenlist *L,int i) { if((i < 0) || (i > L -> length)) { printf("error,please input the right 'i'n"); return 0; } else { for( ; i < L -> length; i++) L -> list[i] = L -> list[i+1]; L -> length = L -> length - 1; return 1; } } //输出顺序表 void printout(sequenlist *L) { int i; for(i = 0; i <= L -> length; i ++) { printf("list[%d]=",i); printf("%cn",L->list[i]); } } main() { sequenlist *L; char cmd,x; int i; L = (sequenlist *)malloc(sizeof(sequenlist)); creatlist(L); do { printf(" i,I 插入n"); printf(" d,D 删除n"); printf(" q,Q 退出n"); do { fflush(stdin); scanf("%c", &cmd); } while((cmd !='d') && (cmd != 'D') && (cmd != 'q') && (cmd != 'Q') && (cmd != 'i') && (cmd != 'I')); switch(cmd) { case 'i': case 'I': printf("请输入你要插入的数据:"); fflush(stdin); scanf("%c", &x); printf("请输入你要插入的位置:"); scanf("%d", &i); insert(L,x,i); printout(L); break; case 'd': case 'D': printf("请输入你要删除的数据的位置:"); fflush(stdin); scanf("%d", &i); dellist(L,i); printout(L); break; } } while((cmd != 'q') && (cmd != 'Q')); }
三、单链表
C语言中用带指针的结构体类型来描述
包含的基本操作有:
1.建立单链表: linklist creat (int n)
2.插入一个元素: Status insert ( linklist &l,int i, Elemtype e)
3.删除一个元素: Status delect ( linklist &l,int i, Elemtype &e)
4.输出单链表: void output (linklist head)
5.查找元素: Status GetElem(linklist l,int i,Elemtype &e )
建立单链表
1
2动态地建立单链表的常用方法有如下两种:**头插入法,尾插入法**。
1.头插法
从一个空表开始,重复读入数据,生成新结点,将读入数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头上,直到读入结束标志为止。即每次插入的结点都作为链表的第一个结点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18linklist creat (int n)//创建单链表,采用头插法建表 { linklist head,p; //定义头指针head指针,p指针指向当前新生成的结点 int x,i; head=(node *)malloc(sizeof(node));//生成头结点 head->next=NULL; printf("输入数字:n"); for(i=n;i>0;i--)//for 循环用于生成第一个节点并读入数据 { scanf("%d",&x); p=(node *)malloc(sizeof(node)); p->data=x;//读入第一个节点的数据 p->next=head->next;//把第一个节点始终插在头结点的后面 head->next=p;//循环以便于生成第二个节点 } return head;//返回头指针 }
2.尾插法
先开辟头指针,然后陆续为每个数据元素开辟存储空间并赋值,并及时将地址送给前面的指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include<stdio.h> #include<stdlib.h> typedef struct liu{ char data; struct liu *next; }test; liu *p,*head; int m=sizeof(test); void build() //字母链表的生成,要一个一个慢慢链入 { int i; head = (test*)malloc(m); //m=sizeof(test) 前面已求出 p = head; for(i = 1; i < 26; i ++) //因尾结点要特殊处理,故i≠26 { p -> data = i+‘a’-1; // 第一个结点值为字符a p -> next = (test*)malloc(m); p = p->next;} //让指针变量P改为指向后继结点 p -> data = i + ‘a’-1; //最后一个元素要单独处理 p -> next = NULL ; } //单链表尾结点的指针域要置空! void display() /*字母链表的输出*/ { p = head; while (p->next!=NULL) { printf("%c",p->data); p = p->next; } printf(“%cn”,p->data); }
单链表的插入
插入运算是将值为e的新结点插入到表的第i个结点的位置上,即插入到ai-1与ai之间。因此,必须首先找到ai-1所在的结点p,然后生成一个数据域为e的新结点s,s结点作为p的直接后继结点。
核心语句
s->next = p->next;
p->next = s ;
元素e结点应预先生成:
s=(LinkList*)malloc(m);
s->data=e;
s->next=p->next
单链表第i个数据插入结点的算法思路:
1.声明一指针p指向链表头结点,初始化j从0开始
2.当j<i-1时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
3.若到链表末尾p为空,则说明第i个结点不存在;
4.否则查找成功,在系统中生成一个空结点s;
5.将数据元素e赋值给s->data;
6.单链表的插入标准语句s->next=p->next; p->next=s;
7.返回成功。
单链表的删除
为了删除第i个结点ai,必须找到结点的存储地址。该存储地址是在其直接前趋结点ai-1的next域中,因此,必须首先找到ai-1的存储位置p,然后令p–>next指向ai的直接后继结点,即把ai从链上摘下。最后释放结点ai的空间,将其归还给“存储池”。
删除结点的核心语句:
q = p->next; //保存b的指针,靠它才能指向c
p->next=q->next; //a、c两结点相连
free(q) ; //删除b结点,彻底释放
单链表第i个数据删除结点的算法思路:
1.声明一指针p指向链表头结点,初始化j从0开始
2.当j<i-1时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
3.若到链表末尾p为空,则说明第i个结点不存在;
4.否则查找成功,将欲删除的结点p->next赋值给q
5.单链表的删除标准语句p->next=q->next;
6.将q结点中的数据赋值给e,作为返回;
7.释放q结点;
8.返回成功。
元素的查找
查找链表第i个数据的算法思路:
1.声明一指针p指向链表第一个结点,初始化j从1开始;
2.当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1;
3.若到链表末尾p为空,则说明第i个结点不存在;
4.否则查找成功,返回结点p的数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175#include "stdio.h" #include "malloc.h" typedef char Elemtype; typedef struct node //定义存储节点 { Elemtype data; struct node *next; } node,*linklist; //建立单链表 linklist creat(int n); //插入元素 int insert(linklist &l, int i, Elemtype e); //删除元素 int delect(linklist &l, int i, Elemtype &e); //查找元素 int GetElem(linklist l, int i, Elemtype &e); //输出单链表 void output(linklist head); //建立单链表,采用头插法建表 linklist creat(int n) { linklist head,p; //定义头指针head指针,p指针指向当前新生成的结点 int x,i; head = (node*)malloc(sizeof(node)); //生成头结点 head ->next = NULL; printf("输出数字:n"); for(i = n; i > 0; i --) //for 循环用于生成第一个节点并读入数据 { scanf("%d", &x); p = (node*)malloc(sizeof(node)); p -> data = x; //读入第一个节点的数据 p -> next = head -> next; //把第一个节点始终插在头结点的后面 head -> next = p; } return head; } //插入元素 int insert(linklist &l, int i, Elemtype e) { int j = 0; linklist p = l, s; while( j < i - 1 && p) { p = p -> next; ++ j; } if( !p || j > i -1) printf("无法插入"); else { s = (node*)malloc(sizeof(node)); s -> data = e; s -> next = p -> next; p -> next = s; } return 1; } //删除元素 int delect(linklist &l, int i, Elemtype &e) { int j = 0; linklist p = l,q; while( j < i - 1 && p -> next) { p = p -> next; ++ j; } if( !p -> next || j > i - 1) printf("无法删除"); else { q = p -> next; p -> next = q -> next; e = q ->data; free(q); } return 1; } //查找元素 int GetElem(linklist l, int i, Elemtype &e) { linklist p; int j; p = l -> next; j = 1; while( p && j < i) { p = p -> next; ++ j; } if( !p || j > i) printf("无法查找"); e = p -> data; return e; } //输出单链表 void output(linklist head) { linklist p; p = head -> next; do { printf("%3d", p -> data); p = p -> next; } while(p); printf("n"); } main() { linklist la; int n; int i,j; Elemtype e; char cmd; printf("输出链表元素的个数:"); scanf("%d", &n); la = creat(n); printf("输出链表:n"); output(la); do { printf("g,G 查找n"); printf("i,I 插入n"); printf("d,D 删除n"); printf("q,Q 退出n"); do { scanf("%c", &cmd); } while((cmd != 'g') && (cmd != 'G') && (cmd != 'd') && (cmd != 'D') && (cmd != 'q') && (cmd != 'Q') && (cmd != 'i') && (cmd != 'I')); switch(cmd) { case 'g': case 'G': printf("请输入要查找元素的位置:n"); scanf("%d", &i); j = GetElem(la, i, e); printf("要查找的元素是%dn", j); break; case 'i': case 'I': printf("请输入你要插入的数据:"); scanf("%d", &e); printf("请输入你要插入的位置:"); scanf("%d", &i); insert(la, i ,e); printf("插入后的链表:n"); output(la); break; case 'd': case 'D': printf("请输入要删除的位置:n"); scanf("%d",&i); delect(la,i,e); printf("删除的那个元素是:%dn",e); printf("输出删除后的顺序表:n"); output(la); break; } } while((cmd != 'q')&&(cmd != 'Q')); }
最后
以上就是勤恳唇膏最近收集整理的关于实验一 顺序表和单链表的建立和操作的全部内容,更多相关实验一内容请搜索靠谱客的其他文章。
发表评论 取消回复