c语言单向链表

匿名 (未验证) 提交于 2019-12-02 23:57:01

一、链表概述  

  链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一个“头指针”变量,以head表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。因此,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。

二、链表创建、删除、插入等如下,将函数与声明定义进行分离为.h和.c:

2.1 linklist.h

 1 #pragma once  2 typedef struct list  3 {  4     int data;//数据域  5     struct list *next;//指针域  6 }LinkList;  7 LinkList *crate_list();    //建立一个节点  8 void traverse(LinkList*ls);//循环遍历链表  9 LinkList* insert_list(LinkList* ls, int n, int data);//在指定位置插入元素 10 int delete_list(LinkList* ls, int n);//删除指定位置元素 11 int count_list(LinkList* ls);//返回链表元素的个数 12 void clear_list(LinkList *ls);//清空链表,只保留首节点 13 int empty_list(LinkList *ls);//返回链表是否为空 14 LinkList *local_list(LinkList*ls, int n);//返回链表指定的位置节点 15 LinkList * elem_list(LinkList* ls, int data);//返回指定位置data 16 int elem_pos(LinkList *ls, int data);//返回数据域等于DATA的位置 17 LinkList *last_list(LinkList *ls);//得到链表的最后一个节点 18 void merge_list(LinkList * s1,LinkList* s2);//合并两个链表 19 void reverse_lsit(LinkList *ls);//链表反转

  1 #include<stdio.h>   2 #include<stdlib.h>   3 #include "linlist.h"   4 //建立一个节点   5 LinkList * crate_list()   6 {   7     return (LinkList*)calloc(sizeof(LinkList),1);   8 }   9 //循环遍历链表  10 void traverse(LinkList * ls)  11 {  12     LinkList *p = ls;  13     while (p)  14     {  15         printf("%d\n",p->data);  16         p = p->next;  17     }  18   19 }  20 //插入元素  21 LinkList * insert_list(LinkList * ls, int n, int data)  22 {  23     LinkList *p = ls;  24     while (p&&n--)  25     {  26         p = p->next;  27     }  28     if (p==NULL)  29     {  30         return NULL;//n的位置大于链表节点数  31     }  32     LinkList *node = crate_list();//新建一个节点  33     node->data = data;  34     node->next = p->next;  35     p->next = node;  36     return node;  37 }  38 //删除节点  39 int delete_list(LinkList * ls, int n)  40 {  41     LinkList *p = ls;  42     while (p&&n--)  43     {  44         p = p->next;  45     }  46     if (p==NULL)  47     {  48         return -1;  49     }  50     LinkList *tmp = p->next;  51     p->next = p->next->next;  52     free(tmp);  53     return 0;  54 }  55 //返回链表元素的个数  56 int count_list(LinkList * ls)  57 {  58     LinkList *p = ls;  59     int count = 0;  60     while (p)  61     {  62         count++;  63         p = p->next;  64     }  65     return count;  66 }  67 //清空链表,只保留首节点  68 void clear_list(LinkList * ls)  69 {  70     LinkList* p = ls->next;  71     while (p)  72     {  73         LinkList * tmp = p->next;  74         free(p);  75         p = tmp;  76     }  77     ls->next = NULL;//只有首节点,则首节点next实则为NULL  78 }  79 //返回聊表是否为空  80 int empty_list(LinkList * ls)  81 {  82     if (ls->next)  83         return 0;  84     else  85         return -1;  86     return 0;  87 }  88 //返回链表指定位置的节点数据域  89 LinkList * local_list(LinkList * ls, int n)  90 {  91     LinkList* p = ls;  92     while (p&&n--)  93     {  94         p=p->next;  95     }  96     if (p == NULL)  97         return NULL;  98     return p;  99 } 100 //返回指定位置数据域对应的节点 101 LinkList * elem_list(LinkList * ls, int data) 102 { 103     LinkList*p = ls; 104     while (p) 105     { 106         if (p->data = data) 107             return p; 108         p = p->next; 109     } 110     return NULL;//没有找到 111 } 112 //返回数据域等于data的节点位置 113 int elem_pos(LinkList * ls, int data) 114 { 115     LinkList * p = ls; 116     int index = 0; 117     while (p) 118     { 119         index++; 120         if (p->data = data) 121             return index; 122         p = p->next; 123     } 124     return -1;//没有找到索引 125 } 126  127 LinkList * last_list(LinkList * ls) 128 { 129     LinkList * p = ls; 130     while (p->next) 131     { 132         p = p->next; 133     } 134     return p; 135 } 136 //合并两个链表,将结构放在第一个链表中 137 void merge_list(LinkList * s1, LinkList * s2) 138 { 139     //合并连标点节点,不合并链表头 140     last_list(s1)->next = s2->next; 141     free(s2); 142 } 143  144 void reverse_lsit(LinkList * ls) 145 { 146     if (ls->next == NULL) 147         return;//只有只有一个头节点 148     if (ls->next->next == NULL) 149         return; 150     LinkList * last = ls->next;//ls->next为最后一个节点 151     LinkList * pre = ls;//上一个节点的指针 152     LinkList *cur = ls->next;//当前节点 153     LinkList*next = NULL;//下一个节指针 154     while (cur) 155     { 156         next = cur->next; 157         cur->next = pre; 158         pre = cur; 159         cur = next; 160     } 161     ls->next = pre; 162     last->next = NULL; 163 }

 1 #include<stdlib.h>  2 #include<stdio.h>  3 #include"linlist.h"  4 #define Len 10  5 int main()  6 {  7     LinkList *first = crate_list();//创建第一个节点  8     LinkList *second = crate_list();//创建第二个节点  9     LinkList *third = crate_list();//创建第三个节点 10     first->next = second;//指针域第一个节点的指针指向下一节点 11     second->next = third;//指针域第二个节点的指针指向下一节点 12     third->next = NULL;//指针域第三个节点的指针指向下一节点,只有三个元素,所以下一节点为NULL 13     first->data = 1;//数据域第一个元素 14     second->data = 2;//数据域第二个元素 15     third->data = 3;//数据域第二个元素 16     //遍历链表 17     printf("插入前:\n"); 18     traverse(first);//遍历头即可打印整个链表,因为链表是靠指针连接在一起 19     insert_list(first,0,100); 20     printf("插入后:\n"); 21     traverse(first); 22     printf("删除后\n"); 23     delete_list(first,2); 24     traverse(first); 25     printf("--------------------------------------\n"); 26     printf("链表的个数cout=%d\n", count_list(first)); 27     //printf("清空链表,直保留首节点\n"); 28     //clear_list(first); 29     printf("链表的个数cout=%d\n", count_list(first)); 30     printf("%d\n",local_list(first,2)->data); 31     printf("data=%d\n",last_list(first)->data); 32     printf("-----------------------------------------\n"); 33  34     LinkList * pp = crate_list(); 35     for (int i = 0; i < Len; i++) 36     { 37         insert_list(pp,0,i); 38     } 39     merge_list(first,pp); 40     traverse(first); 41     printf("xxxxxxxxxxxxxxxxxxxx"); 42     reverse_lsit(first); 43     traverse(first); 44     return 0; 45 }

2.4 结果显示:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!