数据结构之单链表(C实现)
list.h
#ifndef LIST_H
#define LIST_H
#include <iostream>
#include <stdio.h>
#include <malloc.h>
//定义单链表结点
typedef struct _node
{
int data; //数据
struct _node *next; //指向下一结点
}node,*pNode;
//创建链表
node *create_list();
//从链表头后插入数据
int insert_listHead(pNode head,int data);
//从链表尾后插入数据
int insert_listTail(pNode head, int data);
//遍历链表,并显示每个结点的数据
int show_listData(pNode head);
//求链表中的结点个数 (不包括链表头,指真正存放数据的结点数目)
int getNodeNum(pNode head);
//根据索引查找结点,找到返回所找结点 index=0,对应头结点(不存放数据) index=1,对应第一个数据结点
pNode find_nodeByIndex(pNode head,int index);
//根据数据查找第一个符合结点(后面也可能有结点的数据为所找数据),找到返回所找结点
pNode find_nodeByData(pNode head,int data);
//指定位置插入结点数据
int insert_dataInPos(pNode head,int data,int index);
//从链表中删除第index个结点 index范围为1-nodeNum
int delete_listIndex(pNode head,int index);
//删除整个链表
int delete_listAll(node **head);
//根据索引查找结点,找到修改其值
int modify_nodeByIndex(pNode head,int index,int data);
//将链表排序 ==0,升序 ==1,降序
int sort_list(pNode head,int sortType);
#endif // LIST_H
list.c
#include "list.h"
/*************单链表测试程序************/
//创建链表
node *create_list()
{
pNode head = (pNode)malloc(sizeof(node));
if(!head)
{
printf("malloc error!\n");
// exit(-1); //在iostream中定义
return NULL;
}
head->data = ;
head->next = NULL; //不用指向head,由于不是循环链表且是单链表的尾结点的next腰指向NULL
return head;
}
//从链表头后插入结点数据
int insert_listHead(pNode head,int data)
{
//检测链表是否存在
if(!head)
{
printf("list isnot exist!\n");
;
}
pNode tmpNode = (pNode)malloc(sizeof(node)); //存放插入数据的结点
if(!tmpNode)
{
printf("malloc error!\n");
;
}
//将插入数据存入要插入链表的结点
tmpNode->data = data;
//将tmpNode插入链表头后
tmpNode->next = head->next;
head->next = tmpNode;
;
}
//从链表尾后插入结点数据
int insert_listTail(pNode head, int data)
{
//检测链表是否存在
if(!head)
{
printf("list isnot exist!\n");
;
}
pNode tmpNode = (pNode)malloc(sizeof(node)); //存放插入数据的结点
if(!tmpNode)
{
printf("malloc error!\n");
;
}
//将插入数据存入要插入链表的结点
tmpNode->data = data;
//将tmpNode插入链表尾后
tmpNode->next = NULL; //插入链表插入链表尾后,成为新的尾结点,next要指向NULL
pNode cur = head;
//找到链表尾结点
while(cur->next) //尾结点的next指向NULL,跳出时的cur即为尾结点
{
cur = cur->next;
}
cur->next = tmpNode; //原先尾结点的next指向插入结点
;
}
//遍历链表,并显示每个结点的数据
int show_listData(pNode head)
{
//检测链表是否存在
if(!head)
{
printf("list isnot exist!\n");
;
}
//检测链表是否为空 (“为空”与“不存在”不同,为空说明只有一个结点,刚创建还未插入任何结点)
if(!head->next)
{
printf("list isnot exist!\n");
;
}
pNode cur = head->next; //头结点数据域不保存插入数据,第二个结点才是第一个插入结点
while(cur)
{
printf("%d ",cur->data);
cur = cur->next;
}
printf("\n");
;
}
//求链表中的结点个数 (不包括链表头,指真正存放数据的结点数目)
int getNodeNum(pNode head)
{
; //结点数目
//判断链表是否存在
if(!head)
{
printf("list isnot exist!\n");
;
}
//------
//判断链表是否为空
if(!head->next)
{
printf("list is NULL!\n");
;
}
pNode cur = head->next;
while(cur)
{
nodeNum++;
cur = cur->next;
}
return nodeNum;
}
//根据索引查找结点,找到返回所找结点 index=0,对应头结点(不存放数据) index=1,对应第一个数据结点
pNode find_nodeByIndex(pNode head,int index)
{
//判断链表是否存在
if(!head)
{
printf("list isnot exist!\n");
return NULL;
}
//------
//判断链表是否为空
if(!head->next)
{
printf("list is NULL!\n");
return NULL;
}
//------
int nodeNum = getNodeNum(head);
|| index > nodeNum) //索引必须在允许范围 (1-nodeNum)
{
printf("pos out of range!\n");
return NULL;
}
;
pNode cur = head;
while(cur)
{
i++;
cur = cur->next;
if(i==index)
return cur;
}
return NULL; //不返回,有警告
}
//根据数据查找第一个符合结点(后面也可能有结点的数据为所找数据),找到返回所找结点
pNode find_nodeByData(pNode head,int data)
{
//判断链表是否存在
if(!head)
{
printf("list isnot exist!\n");
return NULL;
}
//------
//判断链表是否为空
if(!head->next)
{
printf("list is NULL!\n");
return NULL;
}
pNode cur = head->next;
while(cur)
{
if(cur->data == data)
return cur;
cur = cur->next;
}
return NULL;
}
//指定位置插入结点数据
int insert_dataInPos(pNode head,int data,int index)
{
//判断链表是否存在
if(!head)
{
printf("list isnot exist!\n");
;
}
//------
//判断链表是否为空
if(!head->next)
{
printf("list is NULL!\n");
;
}
//------
int nodeNum = getNodeNum(head);
|| index > nodeNum) //指定插入位置必须在允许范围
{
printf("pos out of range!\n");
;
}
//由于find_nodeByIndex的参数2范围限制为1-nodeNum,所以index在那里不能为1,要>=2
) //插入到位置1,相当于插入头结点后面
{
insert_listHead(head,data);
}
else //index范围为2-nodeNum
{
pNode tmpNode = (pNode)malloc(sizeof(node));
if(!tmpNode)
{
printf("malloc error!\n");
;
}
tmpNode->data = data;
//获得插入位置的前一个结点-insertFrontNode(新数据结点插入到该结点后面)
pNode insertFrontNode = find_nodeByIndex(head,index-);
if(!insertFrontNode) //未找到要被插入的结点
{
printf("no find insertFrontNode!\n");
;
}
//若index=2,相当于新数据结点插入到原数据结点1后面,所以需要找到原数据结点1
tmpNode->next = insertFrontNode->next;
insertFrontNode->next = tmpNode;
}
;
}
//从链表中删除第index个结点 index范围为2-nodeNum
int delete_listIndex(pNode head,int index)
{
//判断链表是否存在
if(!head)
{
printf("list isnot exist!\n");
;
}
//------
//判断链表是否为空
if(!head->next)
{
printf("list is NULL!\n");
;
}
//------
int nodeNum = getNodeNum(head);
|| index > nodeNum) //index必须在允许范围
{
printf("pos out of range!\n");
;
}
pNode front = find_nodeByIndex(head,index-); //找到要删除结点的前一个结点
if(!front)
{
printf("no find!\n");
;
}
//---------
pNode cur = find_nodeByIndex(head,index); //找到要删除结点
if(!cur)
{
printf("no find!\n");
;
}
//删除该结点
front->next = cur->next;
free(cur);
cur = NULL;
;
}
//删除整个链表
int delete_listAll(node **head)
{
if(*head == NULL)
{
printf("list isnot exist!\n");
;
}
node *cur = (*head)->next;
while(cur)
{
node *tmp = cur;
//在free(tmp);后面,那时cur==tmp已经被释放,cur = cur->next不能正常执行了
cur = cur->next;
free(tmp);
tmp = NULL;
}
free(*head);
(*head) = NULL;
;
}
//根据索引查找结点,找到修改其值
int modify_nodeByIndex(pNode head,int index,int data)
{
pNode modifyNode = find_nodeByIndex(head,index); //找到要修改的结点
modifyNode->data = data;
; //不返回,有警告
}
//将链表排序 ==0,升序 ==1,降序
int sort_list(pNode head,int sortType)
{
//判断链表是否存在
if(!head)
{
printf("list isnot exist!\n");
;
}
//------
//判断链表是否为空
if(!head->next)
{
printf("list is NULL!\n");
;
}
int nodeNum = getNodeNum(head);
int i,j;
; i < nodeNum - ; i++) //冒泡排序法
{
; j < nodeNum - - i; j++)
{
//第一次获取0,1结点 第二次获取1,0结点
node *t_first = find_nodeByIndex(head,j+);
node *t_second = find_nodeByIndex(head,j+);
) //升序
{
if(t_first->data > t_second->data)
{
//交换2个结点的值
int tmp = t_first->data;
t_first->data = t_second->data;
t_second->data = tmp;
}
}
) //降序
{
if(t_first->data < t_second->data)
{
int tmp = t_first->data;
t_first->data = t_second->data;
t_second->data = tmp;
}
}
else
{
printf("parame error!\n");
;
}
}
}
;
}
main.c
#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include "list.h"
using namespace std;
pNode tmpNode;
int main(void)
{
//创建链表
tmpNode = create_list();
if(!tmpNode)
{
printf("malloc error!\n");
;
}
//插入1,3,5,7,9到链表中
;i<;i++)
{
insert_listHead(tmpNode,++i);
}
//插入结点数据
insert_dataInPos(tmpNode,,);
//获取结点数目
printf("nodeNum=%d\n",getNodeNum(tmpNode));
//遍历显示结点数据
printf("showList: ");
show_listData(tmpNode);
//根据索引,返回第3个数据结点 index范围为1-nodeNum
pNode t_node = find_nodeByIndex(tmpNode,);
if(!t_node) //有可能未找到,则返回NULL,那执行t_node->data会造成程序崩溃
printf("no find!\n");
else
printf("t_data:data=%d\n",t_node->data);
//返回数据为1的结点
pNode t_node1 = find_nodeByData(tmpNode,);
if(!t_node1)
printf("no find!\n");
else
printf("t_data:data=%d\n",t_node1->data);
//从链表中删除第1个结点 index范围为2-nodeNum
delete_listIndex(tmpNode,);
printf("showList: ");
show_listData(tmpNode);
//升序后显示结点数据
sort_list(tmpNode,);
printf("sortUp showList: ");
show_listData(tmpNode);
//降序后显示结点数据
sort_list(tmpNode,);
printf("sortUp showList: ");
show_listData(tmpNode);
//删除所有结点
delete_listAll(&tmpNode);
printf("showList: ");
show_listData(tmpNode);
}
结果运行图:

数据结构之单链表(C实现)的更多相关文章
- Python数据结构之单链表
Python数据结构之单链表 单链表有后继结点,无前继结点. 以下实现: 创建单链表 打印单链表 获取单链表的长度 判断单链表是否为空 在单链表后插入数据 获取单链表指定位置的数据 获取单链表指定元素 ...
- javascript数据结构之单链表
下面是用javascript实现的单链表,但是在输出的时候insert方法中存在问题,chrome的console报错说不能读取空的属性,调试了很久都没有通过,先在这里存着,以后再来修改一下. //数 ...
- 数据结构之单链表的实现-java
一.单链表基本概念 单链表是一种链式存取的数据结构,用一组地址任意的存储单元(一般是非连续存储单元)存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点的构成:元素data + 指针next ...
- python 数据结构之单链表的实现
链表的定义: 链表(linked list)是由一组被称为结点的数据元素组成的数据结构,每个结点都包含结点本身的信息和指向下一个结点的地址.由于每个结点都包含了可以链接起来的地址信息,所以用一个变量就 ...
- 数据结构(一) 单链表的实现-JAVA
数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数 ...
- 数据结构 - 静态单链表的实行(C语言)
静态单链表的实现 1 静态链表定义 静态链表存储结构的定义如下: /* 线性表的静态链表存储结构 */ #define MAXSIZE 1000 /* 假设链表的最大长度是1000 */ typede ...
- 数据结构 - 动态单链表的实行(C语言)
动态单链表的实现 1 单链表存储结构代码描述 若链表没有头结点,则头指针是指向第一个结点的指针. 若链表有头结点,则头指针是指向头结点的指针. 空链表的示意图: 带有头结点的单链表: 不带头结点的单链 ...
- 【数据结构】单链表介绍及leetcode206题反转单链表python实现
题目传送门:https://leetcode-cn.com/problems/reverse-linked-list/ 文章目录 单链表介绍 链表 概念 种类 优缺点 单链表(slist) leetc ...
- 数据结构(2):单链表学习使用java实现
单链表是单向链表,它指向一个位置: 单链表常用使用场景:根据序号排序,然后存储起来. 代码Demo: package com.Exercise.DataStructure_Algorithm.Sing ...
- 数据结构:单链表结构字符串(python版)添加了三个新功能
#!/urs/bin/env python # -*- coding:utf-8 -*- #异常类 class stringTypeError(TypeError): pass #节点类 class ...
随机推荐
- hdu3592(差分约束) (线性)
题意:一些牛按序号排成一条直线,有两种要求,A和B距离不得超过X,还有一种是A和B距离不得少于Y,问1和N可能的最大距离. 和poj那题一样,就是多了多组数据. #include<cstring ...
- 【JZOJ4857】Tourist Attractions(Bitset)
题意:给定一个n个点的无向图,求这个图中有多少条长度为4的简单路径. n<=1500 思路: #include<map> #include<set> #include&l ...
- [bzoj5101][POI2018]Powódź_并查集
Powódź bzoj-5101 POI-2018 题目大意:在地面上有一个水箱,它的俯视图被划分成了$n$行$m$列个方格,相邻两个方格之间有一堵厚度可以忽略不计的墙,水箱与外界之间有一堵高度无穷大 ...
- 记 SpringBoot1.* 转 Springoot2.0 遇到的问题
1.拦截器问题 到2.0之后在配置文件中写 static-path-pattern: /static/** 已经不起作用(2.0需要在方法中配置) SpringBoot1.*写法 @Configura ...
- Linux系统备份还原工具2(TAR/压缩工具)
相比DD备份还原工具,TAR压缩还原工具更加小巧和灵活,但是不能备份MBR.当然可以通过重新安装GRUB来解决MBR的这一问题.同时,TAR的做法也是官方推荐的. 注意:一个硬盘启动时最新经过MBR( ...
- CentOS6 设置AliNetflow 环境
CentOS6 设置AliNetflow 环境 Install OS 这一步略过. 只要保证操作系统是CentOS6.4 并且网络通畅 Install Python2.7.8 设置YUM 我的网络环境 ...
- 怎样用ccache加速cocos2d-x android版本号的编译
下面步骤在MAC下測试通过: 首先是安装CCache, 能够用homebrew brew install --HEAD ccache 也能够用源代码安装 git clone https://githu ...
- C# MVC 用户登录状态判断 【C#】list 去重(转载) js 日期格式转换(转载) C#日期转换(转载) Nullable<System.DateTime>日期格式转换 (转载) Asp.Net MVC中Action跳转(转载)
C# MVC 用户登录状态判断 来源:https://www.cnblogs.com/cherryzhou/p/4978342.html 在Filters文件夹下添加一个类Authenticati ...
- python包格式
1 egg和wheel 前者扩展名是.egg,后者扩展名是.whl 它们都是python的模块.后者用来替换前者. wheel是轮子的意思,就是说,有了.whl包就不需要重新再造轮子了.
- 说说循环与闭包——《你不知道的JS》读书笔记(一)
什么是闭包 <你不知道的JS>里有对闭包的定义:"当函数可以记住并访问所在的词法作用域,即使函数是在当前作用域之外执行,这就产生了闭包." 讲闭包是啥的太多了...就一 ...