数据结构之链表(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\n",is_empty(pHead));
 39     printf("链表的长度:");
 40     printf("%d\n",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("分配失败,程序终止!\n");
 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("分配失败,程序终止!\n");
 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("\n");
 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("动态内存分配失败!\n");
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 }
时间: 2024-10-24 23:43:01

数据结构之链表(C语言实现)的相关文章

数据结构之链表C语言实现以及使用场景分析

牢骚:本篇博客两个星期前已经存为草稿,鉴于发生一些糟糕的事情,今天才基本完成.本人6月份应届毕业生一枚,毕业后当天来到帝都,之后也非常顺利,面试了俩家公司都成功了.一家做C++方面电商ERP,一家做wifi模块,觉得第二家公司小,薪资低,但是觉得好玩就去了.同时,在学校也喝了不少鸡汤,觉得公司小怎么了.然而去了不到20天,公司被深圳一家公司收购了,公司动员我去深圳,我尼玛我才来20多天啊,有木有?而且感觉公司做这么大的决定都是随时拍板的吗? 原本以为一个公司的生命力强到可以忽略的概率,然而当自己

《数据结构与算法分析—C语言描述》pdf

下载地址:网盘下载 内容简介 编辑 <数据结构与算法分析:C语言描述(原书第2版)>内容简介:书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能.效率以及对运行时间分析的基础上考查了一些高级数据结构,从历史的角度和近年的进展对数据结构的活跃领域进行了简要的概括.由于<数据结构与算法分析:C语言描述(原书第2版)>选材新颖,方法实用,题例丰富,取舍得当.<数据结构与算法分析:C语言描述(原书第2版)>的目的是培养学生良好的程序设计技巧和熟练的算

数据结构——动态链表

说明:严蔚敏的<数据结构>(C语言版)学习笔记,记录一下,以备后面查看. #include <stdio.h> #include <malloc.h> const int OK = 1; //定义正确返回 const int ERROR = -1; //定义错误的返回 const int OVERFLOW = -2; //定义溢出 //定义元素类型 typedef int ElemType; //定义返回类型 typedef int Status; typedef st

前端学数据结构之链表

前面的话 本文将介绍如何实现和使用链表这种动态的数据结构 数据结构 要存储多个元素,数组(或列表)可能是最常用的数据结构.每种语言都实现了数组.这种数据结构非常方便,提供了一个便利的[]语法来访问它的元素.然而,这种数据结构有一个缺点:(在大多数语言中)数组的大小是固定的,从数组的起点或中间插入或移除项的成本很高,因为需要移动元素 链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的.每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成.下图展示

数据结构--单向链表

C语言中,我们在使用数组时,会需要对数组进行插入和删除的操作,这时就需要移动大量的数组元素,但在C语言中,数组属于静态内存分配,数组在定义时就必须指定数组的长度或者初始化.这样程序一旦运行,数组的长度就不能再改变,若想改变,就只能修改源代码.实际使用中数组元素的个数也不能超过数组元素的最大长度,否则就会发生下标越界的错误(这是新手在初学C语言时肯定会遇到的问题,相信老师也会反复强调!!!但这种问题肯定会遇到,找半天找不到错误在哪,怪我咯???).另外如果数组元素的使用低于最大长度,又会造成系统资

数据结构:单向链表系列6--交换相邻两个节点1(交换数据域)

给定一个单向链表,编写函数交换相邻 两个元素 输入: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 输出: 2 -> 1 -> 4 -> 3 -> 6 -> 5 -> 7 输入: 1 -> 2 -> 3 -> 4 -> 5 -> 6 输出: 2 -> 1 -> 4 -> 3 -> 6 -> 5 通过观察发现:当输入的与元素个数是单数的时候,最后一位不参与交换

数据结构-单链表-类定义2-C++

上一次的C++链表实现两个单链表的连接不太理想,此次听了一些视频课,自己补了个尾插法,很好的实现了两个链表的连接,当然了,我也是刚接触,可能是C++的一些语法还不太清楚,不过硬是花了一些时间尽量在数据结构中将c++的语言特点表现出来.一开始也是不愿意读c++的数据结构,只是一种挑战心里,不想读着读着感觉自己太low了,c++的内容更加丰富,所以还得多多练习...... 头文件 1 #ifndef LIST_H 2 #define LIST_H 3 #include <iostream> 4 5

基本数据结构:链表(list)

copy from:http://www.cppblog.com/cxiaojia/archive/2012/07/31/185760.html 基本数据结构:链表(list) 谈到链表之前,先说一下线性表.线性表是最基本.最简单.也是最常用的一种数据结构.线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的.线性表有两种存储方式,一种是顺序存储结构,另一种是链式存储结构. 顺序存储结构就是两个相邻的元素在内存中也是相邻的.这种存储方式的优点是

(续)顺序表之单循环链表(C语言实现)

单循环链表和单链表的唯一区别在于单循环链表的最后一个节点的指针域指向第一个节点, 使得整个链表形成一个环. C实现代码如下: #include<stdio.h> typedef struct node { int data; struct node *next; }Node; //链表的初始化 Node* InitList(int number) { int i; Node *pHead=(Node *)malloc(sizeof(Node)); Node *TempHead=pHead; N

数据结构之链表单向操作总结

链表是数据结构的基础内容之一,下面就链表操作中的创建链表.打印链表.求取链表长度.判断链表是否为空.查找结点.插入结点.删除结点.逆转链表.连接链表.链表结点排序等进行总结. 1.创建表示结点的类,因为链表操作中需要比较结点,因此结点需要实现comparable接口. public class Node implements Comparable<Node> { private Object data; private Node next; //构造函数 public Node() { thi