• 数据结构之链表(C语言实现)


      1 #include<stdio.h>
      2 #include<malloc.h>
      3 #include<stdlib.h>
      4 typedef struct Node     ///定义一个结点(结构体)
      5 {
      6     int data;           ///数据域
      7     struct Node * pNext;///指针域:一个结点的指针与指向的是下一个结点!而不是下一个结点的指针域,更不是下一个结点的数据域
      8 }NODE,*PNODE;           ///NODE等价于struct Node;PNODE等价于struct Node*
      9 
     10 ///下面是对各种函数的声明
     11 PNODE create_list(void);
     12 void traverse_list(PNODE pHead);
     13 int is_empty(PNODE pHead);
     14 int length_list(PNODE pHead);
     15 int sort_list(PNODE pHead);
     16 int insert_list(PNODE pHead,int pos,int val);
     17 int delet_list(PNODE pHead,int pos,int *pVal);
     18 
     19 ///主函数
     20 int main()
     21 {
     22     PNODE pHead=NULL;         ///等价于struct Node *pHead = NULL;
     23     pHead=create_list();      ///创建一个非循环单链表,并将该链表的地址赋给pHead
     24     traverse_list(pHead);
     25     printf("请输入插入元素的位置和插入的元素值:");
     26     int pos1,val1;
     27     scanf("%d%d",&pos1,&val1);
     28     insert_list(pHead,pos1,val1);
     29     printf("插入后的链表:");
     30     traverse_list(pHead);
     31     printf("请输入要删除的元素位置和元素的值:");
     32     int pos2,val2;
     33     scanf("%d%d",&pos2,&val2);
     34     delet_list(pHead,pos2,&val2);
     35     printf("删除后的链表:");
     36     traverse_list(pHead);
     37     printf("链表是否为空:");
     38     printf("%d
    ",is_empty(pHead));
     39     printf("链表的长度:");
     40     printf("%d
    ",length_list(pHead));
     41     sort_list(pHead);
     42     printf("链表排序结果为:");
     43     traverse_list(pHead);
     44     return 0;
     45 }
     46 
     47 PNODE create_list(void)                      ///创建链表
     48 {
     49     int len;                                 ///存放有效结点的个数
     50     int i;
     51     int val;                                 ///用来临时存放用户输入的结点的值
     52 
     53     PNODE pHead=(PNODE)malloc(sizeof(NODE)); ///为结点动态分配内存
     54     if(NULL==pHead)
     55     {
     56         printf("分配失败,程序终止!
    ");
     57         exit(-1);
     58     }
     59     PNODE pTail=pHead;                       ///初始化头结点和尾结点,使尾结点指向头结点的位置,说明该链表没有有效结点
     60     pTail->pNext=NULL;                       ///尾结点的尾指针指向为空,说明尾指针之后无结点
     61 
     62     printf("请输入您需要生成的链表节点的个数:len=");
     63     scanf("%d",&len);
     64 
     65     for(i=0;i<len;i++)
     66     {
     67         printf("请输入第%d个节点的值:",i+1);
     68         scanf("%d",&val);
     69 
     70         PNODE pNew=(PNODE)malloc(sizeof(NODE));///生成了一个新结点 pNew,作为添加新结点的临时储存单元。
     71         if(NULL==pNew)
     72         {
     73             printf("分配失败,程序终止!
    ");
     74             exit(-1);
     75         }
     76         pNew->data=val;      ///把输入的数据存在新结点的数据域
     77         pTail->pNext=pNew;   ///使链表原有的尾指针指向新结点
     78         pNew->pNext=NULL;    ///将新结点的尾指针指向置空(这跟尾指针初始化的操作一样,是在为下一步将pTail赋值为pNew做准备)
     79         pTail=pNew;          ///将pTail赋值为pNew,pNew结点成为了新的尾结点
     80     }
     81     return pHead;
     82 }
     83 
     84 void traverse_list(PNODE pHead)  ///遍历链表并输出
     85 {
     86     PNODE p=pHead->pNext;
     87     while(NULL!=p)
     88     {
     89         printf("%d ",p->data);
     90         p=p->pNext;
     91     }
     92     printf("
    ");
     93 }
     94 
     95 int is_empty(PNODE pHead)        ///判断链表是否为空(链表不存在满的状态!所以没有判断链表是否为满的函数)
     96     {
     97         if(NULL==pHead->pNext)   ///当链表为空时,头结点与尾结点指向相同,所以头结点(可以看作尾结点)的指针指向为空
     98             return 1;
     99         else
    100             return 0;
    101     }
    102 
    103 int length_list(PNODE pHead)     ///计算链表长度
    104 {
    105     PNODE p=pHead->pNext;
    106     int len=0;
    107     while(NULL!=p)               ///设置计数器,直到p为空时计数结束
    108         {
    109             len++;
    110             p=p->pNext;
    111         }
    112     return len;
    113 }
    114 
    115 int sort_list(PNODE pHead)      ///排序(这里使用的是简单的冒泡排序(排序问题不是该程序的重点,不再赘述),也可以用其他排序代码替换此函数内的代码)
    116 {
    117     int i,j,t;
    118     int len=length_list(pHead);
    119     PNODE p,q;
    120 
    121     for(i=0,p=pHead->pNext;i<len-1;++i,p=p->pNext)
    122     {
    123         for(j=i+1,q=p->pNext;j<len;++j,q=q->pNext)
    124         {
    125             if(p->data>q->data)
    126             {
    127                 t=p->data;
    128                 p->data=q->data;
    129                 q->data=t;
    130             }
    131         }
    132     }
    133     return 0;
    134 }
    135 
    136 ///插入和删除的本质是一样的,关键点在于:对某一个结点操作时,必须依靠它的前一个结点,依此类推。除非已经用新的变量名保存了该结点
    137 int insert_list(PNODE pHead,int pos,int val)  ///插入元素
    138 {
    139     int i=0;
    140     PNODE p=pHead;
    141     while(NULL!=p&&i<pos-1)
    142     {
    143         p=p->pNext;
    144         ++i;
    145     }
    146     if(i>pos-1||NULL==p)
    147         return 0;
    148     PNODE pNew=(PNODE)malloc(sizeof(NODE));
    149     if(NULL==pNew)
    150     {
    151         printf("动态内存分配失败!
    ");
    152         exit(-1);
    153     }
    154     ///注意以下四行代码
    155     pNew->data=val;///
    156     PNODE q=p->pNext;///
    157     p->pNext=pNew;///
    158     pNew->pNext=q;///
    159     return 1;
    160 }
    161 
    162 int delet_list(PNODE pHead,int pos,int *pVal)   ///删除元素
    163 {
    164     int i=0;
    165     PNODE p=pHead;
    166     while(NULL!=p->pNext&&i<pos-1)
    167     {
    168         p=p->pNext;
    169         ++i;
    170     }
    171     if(i>pos-1||NULL==p->pNext)
    172         return 0;
    173     ///注意以下三行代码
    174     PNODE q=p->pNext;///
    175     *pVal=q->data;///
    176     p->pNext=p->pNext->pNext;///
    177     free(q);
    178     q=NULL;
    179     return 1;
    180 }
    向代码最深处出发~!
  • 相关阅读:
    1021. 从前有座山——java
    1004. 西西弗斯式的命运——java
    1025. 水枪灭火——java
    1020. 分解质因数——java
    1024.排序——C语言
    1024. 排序——java
    1022. Fib数列——java
    1006. 求和游戏——java
    1005. 数独——java
    SpringBoot 升级到 2.1 后,启动程序时控制台不打印 API 的解决方法及一些感想
  • 原文地址:https://www.cnblogs.com/auto1945837845/p/5384993.html
Copyright © 2020-2023  润新知