zoukankan      html  css  js  c++  java
  • 链表的增删改查

    现在把以前学的数据结构知识再理一遍,上机测试。首先最重要的是链表。在我看来,链表其实就是由一个个结构体连接而成的,创建一个链表有多种方式,头插法,尾插法等,这里采用的是尾插法。表述有不对的地方,欢迎更正,一起进步。

    思路如下:

    1.链表的创建

    首先,采用尾插法创建一个动态链表,并返回改链表的头结点。

    第一步,设置一个头结点head和尾结点tail,刚开始这两个结点的指针域相同;

    第二步,去开辟一个新的结点pnew,并为该结点的数据域赋值;

    第三步,让尾结点指向新结点,tail->pnew,代码表示即为tail->next=pnew,相当与有一条链子把tail和pnew这两个结点连接起来了;

    第四步,既然是尾插法,那么下一个新的结点也是插在尾结点tail的后面啦,经过第三步,可知尾结点变成刚开始的pnew(此时,它才是尾巴!),所以必须将tail变成尾结点,即tail=pnew;

    最后最后,一定要让尾结点指向空地址,方便后面的遍历。

    2.链表的遍历。

    有了头结点(头结点是我们没有预先赋值哦,它的下一个结点才是我们要遍历的第一个结点),我们就可以通过这个头开始按顺序访问链表中的每个结点了,当然,在访问完到最后一个结点时,就停止遍历了,那么停止的条件就是当phead指向空时,所有上面我们为什么要让尾结点指向空。还有一点,phead只是方便遍历这个链表的一个临时结点,如果直接用链表的头结点head来 遍历,下一次对链表进行操作时(遍历,插入,删除等),就很难了,你想想头都不见了,就很尴尬。

    3.链表结点的删除

    定义两个相邻的指针p1和p2分别指向链表head的head->next,根据自己想要删除结点的位置,这两个指针进行移动(始终相邻),最后p2指向的结点即为将要删除的结点。

    4.链表结点的添加

    先去创造一个新的结点pnew,也定义两个相邻的指针p1和p2指向链表head和head->next,同理进行移动,然后只需在p1和p2中间插入新节点,很简单,就是让p1->next为pnew,pnew->next为p2

    5.链表结点的修改

    相对于前面的删除、添加,这个操作更简单。只需定义一个指针p,根据需要修改的地方进行移动,移动到待修改的结点,改变其数据域即可。

      1 #define _CRT_SECURE_NO_WARNINGS
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <stdbool.h>
      5 int NodeNum = 0;            //统计结点个数
      6 typedef struct Node
      7 {
      8     int data;
      9     struct Node* next;
     10 }NODE,*PNODE;
     11 
     12 //创建一个动态链表并返回其头指针
     13 PNODE CreatList()
     14 {
         printf("输入数据,以0结束输入 ");
    15 PNODE head = (PNODE)malloc(sizeof(NODE)); 16 PNODE tail = head; 17 int num = 0; 18 int Flag = 1; 19 scanf("%d", &num); 20 //输入数据,以0结束 21 while (num) 22 { 23 PNODE pnew = (PNODE)malloc(sizeof(NODE)); 24 pnew->data = num; 25 tail->next = pnew; 26 tail = pnew; 27 NodeNum++; 28 scanf("%d", &num); 29 } 30 31 tail->next = NULL; 32 return head; 33 } 34 //遍历链表 35 void tarverse(PNODE head) 36 { 37 PNODE phead = head->next; 38 while (phead != NULL) 39 { 40 printf("%d ", phead->data); 41 phead = phead->next; 42 } 43 printf("一共有%d个结点 ", NodeNum); 44 } 45 //判断是否为空链表 46 bool isEmpty(PNODE head) 47 { 48 if (head->next = NULL) 49 { 50 printf("链表为空 "); 51 return true; 52 } 53 else 54 return false; 55 } 56 //删除结点 57 void DelNode(PNODE head) 58 { 59 int location = 0; 60 printf("删除第几个结点?"); 61 scanf("%d", &location); 62 PNODE p1 = head; 63 PNODE p2 = p1->next; 64 for (int i = 0; i < location-1; i++) 65 { 66 p1 = p1->next; 67 p2 = p2->next; 68 } 69 p1->next = p2->next; 70 free(p2); 71 p2 = NULL; 72 NodeNum--; 73 } 74 //增加结点 75 int AddNode(PNODE head) 76 { 77 PNODE p1 = head; 78 PNODE p2 = p1->next; 79 int location = 0; 80 int newdata = 0; 81 printf("添加在第几个位置?"); 82 scanf("%d", &location); 83 printf("输入新结点数据:"); 84 scanf("%d", &newdata); 85 PNODE pnew = (PNODE)malloc(sizeof(NODE)); 86 pnew->data = newdata; 87 for (int i = 0; i < location - 1; i++) 88 { 89 p1 = p1->next; 90 p2 = p2->next; 91 } 92 p1->next = pnew; 93 pnew->next = p2; 94 NodeNum++; 95 return 0; 96 } 97 //修改结点 98 int AlterNode(PNODE head) 99 { 100 PNODE p = head; 101 int location = 0; 102 int newdata = 0; 103 printf("修改第几个结点?"); 104 scanf("%d", &location); 105 printf("输入新结点数据:"); 106 scanf("%d", &newdata); 107 PNODE pnew = (PNODE)malloc(sizeof(NODE)); 108 pnew->data = newdata; 109 for (int i = 0; i < location; i++) 110 { 111 p = p->next; 112 } 113 p->data = newdata; 114 return 0; 115 } 116 int main() 117 { 118 PNODE p= (PNODE)malloc(sizeof(NODE)); 119 p = CreatList(); 120 tarverse(p); 121 DelNode(p); 122 tarverse(p); 123 AddNode(p); 124 tarverse(p); 125 126 system("pause"); 127 return 0; 128 }
  • 相关阅读:
    【转】Redis主从复制简介
    Redis配置文件详解
    Redis在Windows环境下搭建
    Redis桌面管理工具 RedisDesktopManager
    Redis服务停止报错解决方案[NOAUTH Authentication required]
    Redis启动警告错误解决
    修改tcp内核参数:somaxconn
    CentOS6.8安装Redis3.2.5
    Github之协同开发
    自定义实现栈的功能
  • 原文地址:https://www.cnblogs.com/main404/p/11113639.html
Copyright © 2011-2022 走看看