C语言单链表增删查改详解
2017-11-18 16:07
330 查看
C语言单链表增删查改详解
单链表
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。单链表的建立编辑
链表操作中动态存储分配要使用标准函数,先介绍一下这些函数。(1)malloc(size)
在内存的动态存储区申请一个长度为size字节的连续空间。(2)calloc(n,size)
在内存的动态存储区申请n个长度为size字节的连续空间,函数返回值为分配空间的首地址。若此函数未被成功执行,函数返回值为0。(3)free(p)
释放由指针p所指向的存储单元,而存储单元的大小是最近一次调用malloc()或calloc()函数时所申请的存储空间。在头文件\"stdlib.h”中包含了这些函数的信息,使用这些函数时需在程序开头用文件包含指令#include“stdlib.h”指明。
另请读者注意,调用动态存储分配函数返回的指针是指向void类型或char类型的指针,在具体使用时,要根据所指向的数据进行强制类型转换。
单链表的建立有头插法、尾插法两种方法。
1.头插法
单链表是用户不断申请存储单元和改变链接关系而得到的一种特殊数据结构,将链表的左边称为链头,右边称为链尾。头插法建单链表是将链表右端看成固定的,链表不断向左延伸而得到的。头插法最先得到的是尾结点。由于链表的长度是随机的,故用一个while循环来控制链表中结点个数。假设每个结点的值都大于O,则循环条件为输入的值大于o。申请存储空间可使用malloc()函数实现,需设立一申请单元指针,但malloc()函数得到的指针并不是指向结构体的指针,需使用强制类型转换,将其转换成结构体型指针。刚开始时,链表还没建立,是一空链表,head指针为NULL。
链表建立的过程是申请空间、得到数据、建立链接的循环处理过程。
2.尾插法
若将链表的左端固定,链表不断向右延伸,这种建立链表的方法称为尾插法。尾插法建立链表时,头指针固定不动,故必须设立一个搜索指针,向链表右边延伸,则整个算法中应设立三个链表指针,即头指针head、搜索指针p2、申请单元指针pl。尾插法最先得到的是头结点。代码地址:链接:百度云下载密码:68ni
如图所示:
单链表的增加节点图解:
单链表删除图解:
代码:
/*
单链表:有表头:首节点:数据域没有值,只有一个指针域
---->结构体
1.创建表
2.创建结点
3.插入(表头,指定位置,表尾)
4.删除(表头,指定位置,表尾)
5.判断是否为空
6.打印
*/
#include <iostream>
using namespace std;
/*
创建结点结构体
*/
typedef struct SingleList
{
//数据域--->存储的数据类型
int data;
//指针域--->结构体类型的指针
struct SingleList* next;
}SINGLELIST, *LPSINGLELIST;
//typedef: 定义别名
//struct SingleList :SINGLELSIT
//struct SingleList* :*LPSINGLELIST
/*
声明你要做的事情
*/
//创建一个表---->返回一个表
LPSINGLELIST CreateList();//实质是创建没有data的节点
//创建节点---->返回一个Node
LPSINGLELIST CreateNode(int data);//创建结点要传入数据
//判断是否为空
int IsEmptyList(LPSINGLELIST L);//为空返回1,不为空返回0
//打印
void PrintList(LPSINGLELIST L);//循环遍历打印
//插入
void InsertListHeadNode(LPSINGLELIST L, int data);
void InsertListTailNode(LPSINGLELIST L, int data);
void InsertListAppoinNode(LPSINGLELIST L, int data, int item);
//删除
void DeleteListHeadNode(LPSINGLELIST L);
void DeleteListTailNode(LPSINGLELIST L);
void DeleteListAppoinNode(LPSINGLELIST L, int item);
int main()
{
//创建链表L
LPSINGLELIST L = CreateList();
//测试头插法 3 2 1
InsertListHeadNode(L, 1);
InsertListHeadNode(L, 2);
InsertListHeadNode(L, 3);
//测试表位插入 5 6 7
InsertListTailNode(L, 5);
InsertListTailNode(L, 6);
InsertListTailNode(L, 7);
//测试指定位置插入 3 2 1 4 5 6 7
InsertListAppoinNode(L, 4, 5);
//删除头
DeleteListHeadNode(L);
PrintList(L);
//删除尾部
DeleteListTailNode(L);
PrintList(L);
DeleteListAppoinNode(L, 4);
PrintList(L);
return 0;
}
//-------------->创建表
LPSINGLELIST CreateList()
{
//为链表分配空间
LPSINGLELIST L = (LPSINGLELIST)malloc(sizeof(SINGLELIST));//作业用new
//指针域置空
if (L == NULL)
{
cout << "内存分配失败" << endl;
return NULL;
}
//表头没有数据
L->next = NULL;
return L;
}
//-------------->创建节点
LPSINGLELIST CreateNode(int data)
{
//为Node分配空间
LPSINGLELIST Node = (LPSINGLELIST)malloc(sizeof(SINGLELIST));//作业用new
//指针域置空
if (Node == NULL)
{
cout << "内存分配失败" << endl;
return NULL;
}
//节点数据域的初始化
Node->data = data;
//节点指针域的初始化
Node->next = NULL;
return Node;
}
int IsEmptyList(LPSINGLELIST L)
{
//只有表头节点的时候, 为空
if (L->next == NULL)//容易出错,容易些赋值表达式
return 1;//返回1为空
else
return 0;//返回0不为空
}
//CreateList和CreateNode都必须判断是否为空
//遍历和打印
void PrintList(LPSINGLELIST L)
{
//判断是否为空
if (IsEmptyList(L))
throw 1;
LPSINGLELIST p = L->next;//因为表头没有数据
while (p)
{
cout << " " << p->data;
p = p->next; //递推 i=i+1是一样
}
cout << endl;
}
//----------->插入表头
void InsertListHeadNode(LPSINGLELIST L, int data)
{
//创建节点
LPSINGLELIST Node = CreateNode(data);
//先连接在打断
Node->next = L->next;
L->next = Node;
}
//---------->表位插入
void InsertListTailNode(LPSINGLELIST L, int data)
{
//创建节点
LPSINGLELIST Node = CreateNode(data);
//找到尾节点
//误区:最后一个结点不是指NULL,指NULL的上一个结点
LPSINGLELIST p = L;
while (p->next != NULL)
p = p->next;
p->next = Node;
}
//----------->指定位置插入
void InsertListAppoinNode(LPSINGLELIST L, int data, int item)
{
//创建节点
LPSINGLELIST Node = CreateNode(data);
//讲的是2个指针
//回去尝试一个指针
LPSINGLELIST q = L;
LPSINGLELIST k = L->next;
while (k->data != item)
{
//q和k一直保持相邻,
q = k;
k = q->next;
//未找到
if (k == NULL)
{
cout << "未找到插入位置" << endl;
return;
}
}
//list 排序,有交叉插入 1 3 5 7 9 2 4 6 ===1 2 3 4 5 6 7 9
q->next = Node;
Node->next = k;
}
//----------->删除头
void DeleteListHeadNode(LPSINGLELIST L)
{
//判断是否为空
if (IsEmptyList(L))
exit(0);
LPSINGLELIST p = L->next;
L->next = p->next;
free(p);
}
//------------>删除尾节点
void DeleteListTailNode(LPSINGLELIST L)
{
//判断是否为空
if (IsEmptyList(L))
exit(0);
LPSINGLELIST q = L;
LPSINGLELIST p = q->next;
while (p->next)
{
q = p;
p = q->next;
}
q->next = NULL;
free(p);
}
void DeleteListAppoinNode(LPSINGLELIST L, int item)
{
//判断是否为空
if (IsEmptyList(L))
exit(0);
LPSINGLELIST q = L;
LPSINGLELIST p = L->next;
//找到删除的节点p;
while (p->data != item)
{
q = p;
p = q->next;
if (p == NULL)
{
cout << "未找到指定位置" << endl;
return;
}
}
q->next = p->next;
free(p);
}
多多指教。。。
相关文章推荐
- C语言实现单链表增删查找等功能
- C语言单链表实现19个功能完全详解
- C语言之复杂链表的复制方法(图示详解)
- C语言单向链表的表示与实现实例详解
- C语言指针、链表与文件操作详解
- C语言单链表实现19个功能完全详解
- C语言建立链表以及增删改查
- c语言链表详解
- C语言实现双向链表,增删改查,排序
- c基础之链表-C语言单链表实现19个功能完全详解
- C语言链表详解
- C语言数据结构 链表与归并排序实例详解
- C语言单链表实现19个功能完全详解
- C语言之双向链表详解及实例代码
- c语言-指针实现链表增删改查
- (转载)C语言单链表实现19个功能完全详解
- 单链表的实现和相关面试题及其详解(C语言)
- C语言之单向链表详解及实例代码
- C语言链表各类操作详解
- 第一次写C语言链表的增删改查