单链表的几种基本操作,增删改查
//基本结构
typedef int dataType;
typedef struct _node
{
dataType data;
//单链表中的数据域
struct _node *next;
//单链表的指针域
}LinkNode,*LinkedList;
//结点由存放数据元素的数据域和存放后续结点地址的指针域组成//1.创建结点,当data为NULL时表示创建头结点
LinkedList listCreatNode(dataType data)
{
LinkedList p = NULL;
p = (LinkedList)malloc(sizeof(LinkNode));
if(p == NULL)
{
perror("listCreatNode err");
return NULL;
}
p->data = https://www.it610.com/article/data;
p->next = NULL;
return p;
}//2.头插法 每次新创建的结点总是头结点的下一跳
int listInsertHead(LinkedList L,dataType data)
{
LinkedList node = listCreatNode(data);
if(node == NULL)
{
perror("listCreatNode err");
return -1;
}
node->next = L->next;
//让新结点的下一跳等于头结点的下一跳(后一结点)
L->next = node;
//让头结点的下一跳等于新结点的地址(新插入的结点)
return 0;
}
//3.尾插法 每次新创建的结点都是最后一个结点
int listInsertTail(LinkedList L,dataType data)
{
LinkedList temp;
temp = L;
LinkedList node = listCreatNode(data);
if(node == NULL)
{
perror("listCreatNode err");
return -1;
}
while(temp->next != NULL)//遍历链表到终结点
{
temp = temp->next;
}
temp->next = node;
return 0;
}
//4.按序列号插入
int listInsertIndex(LinkedList L,int i,dataType data)
{
int n = 0;
LinkedList temp = L;
while(temp->next && n < (i-1))
{
n++;
temp = temp->next;
}
if(n < (i-1) || !temp)
{
return -2;
//超出链表长度
}
LinkedList node = listCreatNode(data);
if(node == NULL)
{
perror("listCreatNode err");
return -1;
}
node->next = temp->next;
temp->next = node;
return 0;
}
//5.获取某结点的值,根据第几个结点获取
int listGetValue(LinkedList L,int i,dataType *data)
{
int n = 0;
LinkedList temp = L;
while(temp->next && n < i)
{
n++;
temp = temp->next;
}
if(n < i)
{
return -2;
//超出链表长度
}
*data = https://www.it610.com/article/temp->data;
return 0;
}
//6.根据结点值,获取某结点的地址和结点号
dataType* listGetIndex(LinkedList L,int *i,dataType data)
{
int n = 0;
LinkedList temp = L;
while(temp->next)
{
temp = temp->next;
n++;
if(data =https://www.it610.com/article/= temp->data)
{
*i = n;
return &(temp->data);
}
}
return NULL;
}
//7.修改某结点的值
/*!
* @brief listChangeValue
*修改某结点的值
* @param L传入链表的头结点
* @param olddata要修改的结点数据域的原值
* @param newdata要修改的结点数据域的新值
*-
*-
* @return> 0 修改成功的个数
< 0 修改失败,未找到
*/
int listChangeValue(LinkedList L,dataType olddata,dataType newdata)
{
LinkedList temp = L;
int flag = 0;
while(temp->next)
{
if(temp->data =https://www.it610.com/article/= olddata)
{
temp->data = https://www.it610.com/article/newdata;
flag++;
}
temp = temp->next;
}
if(flag)
return flag;
else
return -1;
}
//8.删除结点
/*!
* @brief listDeleteValue
*删除结点
* @param L传入链表的头结点
* @param data要删除的结点数据域的值
*-
*-
* @return> 0 删除成功的个数
< 0 删除失败,未找到
*/
int listDeleteValue(LinkedList L,dataType data)
{
LinkedList temp = L;
LinkedList tempn = L->next;
int flag = 0;
while(tempn->next)
{if(tempn->data =https://www.it610.com/article/= data)
{
temp->next = tempn->next;
free(tempn);
flag++;
}
temp = temp->next;
tempn = temp->next;
}
if(flag)
return flag;
else
return -1;
}
//9.清空链表
int listClearList(LinkedList L)
{
LinkedList temp = L;
while(L->next)
{
temp = L;
L= L->next;
free(temp);
}
return 0;
}
//10.打印链表printList
int printLinkList(LinkedList L)
{
LinkedList temp = L;
while(temp->next)
{
temp = temp->next;
printf("%4d ",temp->data);
}
printf("\r\n");
return 0;
}
//应用测试
int main()
{//链表
int m_data = https://www.it610.com/article/0,m_index = 0;
LinkedList hList;
hList = listCreatNode(NULL);
//创建头结点for(int i = 100;
i < 110;
i++)
listInsertTail(hList,i);
//创建一个链表
printLinkList(hList);
listInsertHead(hList,99);
//从头结点后插入一个结点
printLinkList(hList);
listInsertIndex(hList,2,98);
//从指定的结点插入一个结点
printLinkList(hList);
listGetValue(hList,2,&m_data);
//获取某个结点的值
printf("getValue=https://www.it610.com/article/%d/r/n",m_data);
listGetIndex(hList,&m_index,103);
//获取结点数据域对应的结点号
printf("getIndex=%d\r\n",m_index);
listChangeValue(hList,105,100);
//修改数据域的值
printLinkList(hList);
listDeleteValue(hList,100);
//删除数据域为指定值的结点
printLinkList(hList);
listClearList(hList);
//释放整个链表system("pause");
return 0;
}
【单链表的增删改查基本操作】测试结果:
100101102103104105106107108109
99100101102103104105106107108109
9998100101102103104105106107108109
getValue=https://www.it610.com/article/98
getIndex=6
9998100101102103104100106107108109
9998101102103104106107108109
请按任意键继续. . .
推荐阅读
- 笔记|C语言数据结构——二叉树的顺序存储和二叉树的遍历
- C语言学习(bit)|16.C语言进阶——深度剖析数据在内存中的存储
- 数据结构和算法|LeetCode 的正确使用方式
- 先序遍历 中序遍历 后序遍历 层序遍历
- 数据结构|C++技巧(用class类实现链表)
- 数据结构|贪吃蛇代码--c语言版 visual c++6.0打开
- 算法|算法-二分查找
- 数据结构学习指导|数据结构初阶(线性表)
- leetcode题解|leetcode#106. 从中序与后序遍历序列构造二叉树
- java|ObjectOrientedProgramming - 面向对象的编程(多态、抽象类、接口)- Java - 细节狂魔