c语言单链表双向链表区别,数据结构之链表篇(单链表,循环链表,双向链表)C语言版...

1.链表

链表是线性表的一种,由一系列节点(结点)组成,每个节点包含一个数据域和一个指向下一个节点的指针域。链表结构可以克服数组需要预先知道数据大小的缺点,而且插入和删除元素很方便,但是失去数组随机读取的优点。链表有很多种不同类型:单向链表,双向链表和循环链表。

在链表中第一个节点叫头节点(如果有头节点)头节点不存放有效信息,是为了方便链表的删除和插入操作,第一个有效节点叫首节点,最后一个节点叫尾节点。

2.单链表的操作

链表的操作一般有创建链表,插入节点,删除节点,遍历链表。插入节点的方法有头插法和尾插法,头插法是在头部插入,尾插法是在尾部插入。

下面以一个带头节点,采用尾插法的链表说明链表的各种操作。

1 #include

2 #include

3 //单链表

4

5

6 //节点结构体

7 typedef struct node

8 {

9 int value;//数据域

10 struct node*next;//指针域

11 }Node;

12

13 Node*createList();//创建链表并且返回头节点指针

14 void deleteNode(Node*head);//删除节点

15 void insertNode(Node*head);//插入节点

16 void travelList(Node*head);//遍历链表

17

18 int main()

19 {

20 Node*head=createList();

21 travelList(head);

22 insertNode(head);

23 travelList(head);

24 deleteNode(head);

25 travelList(head);

26 return 0;

27 }

28 //创建链表,返回头节点指针

29 Node*createList()

30 {

31 //采用尾插法

32 Node*head;//头节点

33 Node*tail;//尾节点

34 Node*temp=NULL;

35 int i,value,size;

36 head=(Node*)malloc(sizeof(Node));//头节点

37 head->value=0;

38 head->next=NULL;

39 tail=head;

40 printf("输入节点个数: ");

41 scanf("%d",&size);

42 printf("输入各个节点的值: ");

43

44 for(i=0;i

45 {

46 scanf("%d",&value);

47 temp=(Node*)malloc(sizeof(Node));

48 temp->value=value;

49 tail->next=temp;//让尾节点的指针域指向新创建的节点

50 tail=temp;//尾节点改为新创建的节点

51 tail->next=NULL;//让尾节点的指针域为空

52 }

53 return head;

54 }

55 //遍历链表

56 void travelList(Node*head)

57 {

58 while(head->next!=NULL)

59 {

60 printf("%d\n",head->next->value);

61 head=head->next;

62 }

63 }

64 //插入节点

65 void insertNode(Node*head)

66 {

67 int value;

68 int position;

69 int pos=0;

70 Node*pre=NULL;//用来保存要插入节点的前一个节点

71 Node*newNode;

72 printf("输入要插入节点的值: ");

73 scanf("%d",&value);

74 printf("要插入的位置: ");

75 scanf("%d",&position);

76 while(head!=NULL)

77 {

78 pos++;

79 pre=head;

80 head=head->next;

81 if(pos==position)

82 {

83 newNode=(Node*)malloc(sizeof(Node));

84 newNode->value=value;

85 newNode->next=pre->next;

86 pre->next=newNode;

87 }

88 }

89 }

90 //删除节点

91 void deleteNode(Node*head)

92 {

93 int value;

94 Node*pre=head;

95 Node*current=head->next;

96 printf("输入要删除节点的值: ");

97 scanf("%d",&value);

98 while(current!=NULL)

99 {

100 if(current->value==value)

101 {

102 pre->next=current->next;

103 free(current);//释放空间

104 break;

105 }

106 pre=current;

107 current=current->next;

108 }

109 }

9d1dcb9b9129dc2c5086fc48fb9726f8.png

3.循环链表

循环链表就是让尾节点的指针域不再是NULL,而是指向头节点从而形成一个环。循环链表与单链表的操作没有多少差别,只是判断链表是否空应该是

tail->next==head。

4.双向链表

双向链表的每一个节点都有两个指针域,一个前驱指针,指向前一个节点,头节点的前驱指针为NULL,一个后继指针,指向后一个节点,尾节点的后继指针为NULL。双向链表可以从任一个节点开始访问到前后节点,不像单链表只能向前。代码如下。

1 #include

2 #include

3 //双向链表

4 typedef struct node

5 {

6 int value;//数据域

7 struct node* lNext;//前驱指针

8 struct node* rNext;//后继指针

9 }Node;

10

11 Node*createList();//创建链表并且返回头节点指针

12 void deleteNode(Node*head);//删除节点

13 void insertNode(Node*head);//插入节点

14 void travelList(Node*head);//遍历链表

15

16 int main()

17 {

18

19 Node*head=createList();

20 travelList(head);

21 insertNode(head);

22 travelList(head);

23 deleteNode(head);

24 travelList(head);

25 return 0;

26 }

27

28 Node*createList()

29 {

30 Node*head,*tail,*temp;

31 int num,value,i;

32 head=(Node*)malloc(sizeof(Node));//头节点

33 head->value=0;

34 head->lNext=NULL;

35 head->rNext=NULL;

36 tail=head;

37 printf("输入节点个数: ");

38 scanf("%d",&num);

39 printf("输入各个节点的值: ");

40 for(i=0;i

41 {

42 scanf("%d",&value);

43 temp=(Node*)malloc(sizeof(Node));

44 temp->value=value;

45 temp->lNext=tail;

46 tail->rNext=temp;

47 tail=temp;

48 tail->rNext=NULL;

49 }

50 return head;

51 }

52

53

54 void deleteNode(Node*head)//删除节点

55 {

56

57 int value;

58 Node*pre;

59 Node*current=head->rNext;

60 printf("输入要删除节点的值: ");

61 scanf("%d",&value);

62 pre=head;

63 while(current!=NULL)

64 {

65 if(current->value==value)

66 {

67 pre->rNext=current->rNext;//上一个节点指向下一个节点

68 current->rNext->lNext=pre;//下一个节点的前驱指针指向上一个节点

69 free(current);//删除该节点

70 }

71 pre=current;

72 current=current->rNext;

73 }

74 }

75

76 void insertNode(Node*head)//插入节点

77 {

78 Node*pre,*temp;

79 int value,pos;

80 int num=0;

81 printf("输入要插入的值: ");

82 scanf("%d",&value);

83 printf("输入要插入的位置: ");

84 scanf("%d",&pos);

85 while(head!=NULL)

86 {

87 num++;

88 pre=head;//保存上一个节点

89 head=head->rNext;//当前节点

90 if(pos==num)

91 {

92 temp=(Node*)malloc(sizeof(Node));

93 temp->value=value;

94 temp->lNext=pre;

95 temp->rNext=head;

96 head->lNext=temp;

97 pre->rNext=temp;

98 }

99 }

100 }

101

102 void travelList(Node*head)//遍历链表

103 {

104 while(head->rNext!=NULL)

105 {

106 printf("%d\n",head->rNext->value);

107 head=head->rNext;

108 }

109 }

d58b363f1870a676aabbaee70df2dbf1.png

其实只要弄懂单链表,其他也很简单的,无论链表多复杂,本质还是操作指针的指向,想想就会明白了。

如果链表不会,后面的各种各样的树结构,就更不用学了。

标签:Node,current,head,单链,value,C语言,链表,节点

来源: https://www.cnblogs.com/duichoumian/p/12836262.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值