C语言数据结构 双向链表的建立与基本操作

2025-05-27 0 30

C语言数据结构 双向链表的建立与基本操作

双向链表比单链表有更好的灵活性,其大部分操作与线性表相同。下面总结双向链表与单链表之间的不同之处及我在实现过程中所遇到的问题。

1.双向链表的建立

双向链表在初始化时,要给首尾两个节点分配内存空间。成功分配后,要将首节点的prior指针和尾节点的next指针指向NULL,这是十分关键的一步,因为这是之后用来判断空表的条件。同时,当链表为空时,要将首节点的next指向尾节点,尾节点的prior指向首节点。

2.双向链表的插入操作

由于定义双向链表时指针域中多了一个prior指针,插入操作相应变得复杂,但基本操作也并不难理解。只需记住在处理前驱和后继指针与插入节点的关系时,应始终把握好“有序原则”,即若将插入节点与两个已存在的节点构成三角形,则应先处理“向上”的指针,再处理“向下”的指针。下面用代码描述其过程:

?

1

2

3

4
pinsert->prior=p;

pinsert->next=p->next;

p->next->prior=pinsert;

p->next=pinsert;

3.双向链表的删除操作

理解了双向链表的插入操作后,删除操作便十分容易理解。下面用代码描述其过程:

?

1

2

3
p->prior->next=p->next;

p->next->prior=p->prior;

free(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

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194
#include<stdio.h>

#include<stdlib.h>

#include<time.h>

#define OK 1

#define ERROR 0

#define TRUE 1

#define FALSE 0

typedef int status;

typedef int elemtype;

typedef struct node{

elemtype data;

struct node * next;

struct node * prior;

}node;

typedef struct node* dlinklist;

status visit(elemtype c){

printf("%d ",c);

}

/*双向链表初始化*/

status initdlinklist(dlinklist * head,dlinklist * tail){

(*head)=(dlinklist)malloc(sizeof(node));

(*tail)=(dlinklist)malloc(sizeof(node));

if(!(*head)||!(*tail))

return ERROR;

/*这一步很关键*/

(*head)->prior=NULL;

(*tail)->next=NULL;

/*链表为空时让头指向尾*/

(*head)->next=(*tail);

(*tail)->prior=(*head);

}

/*判定是否为空*/

status emptylinklist(dlinklist head,dlinklist tail){

if(head->next==tail)

return TRUE;

else

return FALSE;

}

/*尾插法创建链表*/

status createdlinklisttail(dlinklist head,dlinklist tail,elemtype data){

dlinklist pmove=tail,pinsert;

pinsert=(dlinklist)malloc(sizeof(node));

if(!pinsert)

return ERROR;

pinsert->data=data;

pinsert->next=NULL;

pinsert->prior=NULL;

tail->prior->next=pinsert;

pinsert->prior=tail->prior;

pinsert->next=tail;

tail->prior=pinsert;

}

/*头插法创建链表*/

status createdlinklisthead(dlinklist head,dlinklist tail,elemtype data){

dlinklist pmove=head,qmove=tail,pinsert;

pinsert=(dlinklist)malloc(sizeof(node));

if(!pinsert)

return ERROR;

else{

pinsert->data=data;

pinsert->prior=pmove;

pinsert->next=pmove->next;

pmove->next->prior=pinsert;

pmove->next=pinsert;

}

}

/*正序打印链表*/

status traverselist(dlinklist head,dlinklist tail){

/*dlinklist pmove=head->next;

while(pmove!=tail){

printf("%d ",pmove->data);

pmove=pmove->next;

}

printf("\\n");

return OK;*/

dlinklist pmove=head->next;

while(pmove!=tail){

visit(pmove->data);

pmove=pmove->next;

}

printf("\\n");

}

/*返回第一个值为data的元素的位序*/

status locateelem(dlinklist head,dlinklist tail,elemtype data){

dlinklist pmove=head->next;

int pos=1;

while(pmove&&pmove->data!=data){

pmove=pmove->next;

pos++;

}

return pos;

}

/*返回表长*/

status listlength(dlinklist head,dlinklist tail){

dlinklist pmove=head->next;

int length=0;

while(pmove!=tail){

pmove=pmove->next;

length++;

}

return length;

}

/*逆序打印链表*/

status inverse(dlinklist head,dlinklist tail){

dlinklist pmove=tail->prior;

while(pmove!=head){

visit(pmove->data);

pmove=pmove->prior;

}

printf("\\n");

}

/*删除链表中第pos个位置的元素,并用data返回*/

status deleteelem(dlinklist head,dlinklist tail,int pos,elemtype *data){

int i=1;

dlinklist pmove=head->next;

while(pmove&&i<pos){

pmove=pmove->next;

i++;

}

if(!pmove||i>pos){

printf("输入数据非法\\n");

return ERROR;

}

else{

*data=pmove->data;

pmove->next->prior=pmove->prior;

pmove->prior->next=pmove->next;

free(pmove);

}

}

/*在链表尾插入元素*/

status inserttail(dlinklist head,dlinklist tail,elemtype data){

dlinklist pinsert;

pinsert=(dlinklist)malloc(sizeof(node));

pinsert->data=data;

pinsert->next=NULL;

pinsert->prior=NULL;

tail->prior->next=pinsert;

pinsert->prior=tail->prior;

pinsert->next=tail;

tail->prior=pinsert;

return OK;

}

int main(void){

dlinklist head,tail;

int i=0;

elemtype data=0;

initdlinklist(&head,&tail);

if(emptylinklist(head,tail))

printf("链表为空\\n");

else

printf("链表不为空\\n");

printf("头插法创建链表\\n");

for(i=0;i<10;i++){

createdlinklisthead(head,tail,i);

}

traverselist(head,tail);

for(i=0;i<10;i++){

printf("表中值为%d的元素的位置为",i);

printf("%d位\\n",locateelem(head,tail,i));

}

printf("表长为%d\\n",listlength(head,tail));

printf("逆序打印链表");

inverse(head,tail);

for(i=0;i<10;i++){

deleteelem(head,tail,1,&data);

printf("被删除的元素为%d\\n",data);

}

traverselist(head,tail);

if(emptylinklist(head,tail))

printf("链表为空\\n");

else

printf("链表不为空\\n");

printf("尾插法创建链表\\n");

for(i=0;i<10;i++){

//inserttail(head,tail,i);

createdlinklisttail(head,tail,i);

}

traverselist(head,tail);

printf("逆序打印链表");

inverse(head,tail);

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 C语言数据结构 双向链表的建立与基本操作 https://www.kuaiidc.com/74258.html

相关文章

发表评论
暂无评论