1.h文件
#ifndef LINKLIST_H
#define LINKLIST_H
#include<myhead.h>
//定义数据结构
typedef int datatype;
//定义结点结构体
typedef struct Node
{
union
{
int len; //头结点指针域
datatype data; //普通结点指针域
};
struct Node *next; //指针域
}Node, *NodePtr;
//创建链表
NodePtr list_create();
//申请结点封装数据函数
NodePtr apply_node(datatype e);
//链表判空
int list_empty(NodePtr L);
//头插
int list_inset_haed(NodePtr L,datatype e);
//链表遍历函数
int list_show(NodePtr L);
//通过位置查找结点
NodePtr list_seaech_pos(NodePtr L,int pos);
//任意位置插入元素
int List_inset_pos(NodePtr L,int pos,datatype e);
//链表头删
int list_delete_head(NodePtr L);
//任意位置删除
int list_delete_pos(NodePtr L,int pos);
//按数值查找返回位置
int list_search_value(NodePtr L,datatype e);
//按位置进行修改
int list_update_pos(NodePtr L,int pos,datatype e);
//按数值进行修改
int list_update_value(NodePtr L,datatype old_e,datatype new_e);
//翻转链表
void list_revere(NodePtr L);
//链表排序
Node *list_paixu( Node*L);
//用递归的方式进行链表的翻转
void list_diguirevere(NodePtr L);
//链表去重
int list_quchong(NodePtr L);
#endif
1.c文件
#include "1.h"
#include <myhead.h>
//创建链表
NodePtr list_create()
{
//只需要在堆区申请一个头结点
NodePtr L = (NodePtr)malloc(sizeof(Node));
if (NULL == L)
{
printf("创建失败\n");
return NULL;
}
//程序运行至此,说明头结点创建结束
L->len = 0; //表示链表长度为0
L->next = NULL; //防止野指针
printf("创建成功\n");
return L;
}
//申请结点封装数据函数
NodePtr apply_node(datatype e)
{
NodePtr p = (NodePtr)malloc(sizeof(Node));
if (NULL == p)
{
printf("结点申请失败\n");
return NULL;
}
//给结点内容赋值
p->data = e; //数据域赋值
p->next = NULL; //指针域
return p;
}
//链表判空
int list_empty(NodePtr L)
{
return L->next == NULL;
}
//头插
int list_inset_haed(NodePtr L, datatype e)
{
//判断逻辑
if (NULL == L)
{
printf("链表不合法\n");
return -1;
}
//申请结点封装数据
NodePtr p = apply_node(e);
if (NULL == p)
{
return -1;
}
//头插逻辑
p->next = L->next;
L->next = p;
//表的变化
L->len++;
printf("头插成功\n");
return 0;
}
//链表遍历
int list_show(NodePtr L)
{
//判断逻辑
if (NULL == L || list_empty(L))
{
printf("遍历失败\n");
return -1;
}
printf("链表中的数据分别是:\n");
//遍历逻辑
NodePtr q = L->next;
while (q != NULL)
{
//输出数据
printf("%d\t", q->data);
q = q->next;
}
printf("\n");
return 0;
}
//通过位置查找结点
NodePtr list_seaech_pos(NodePtr L, int pos)
{
//判断逻辑
if (NULL == L || list_empty(L) || pos < 0 || pos > L->len)
{
printf("查找失败\n");
return NULL;
}
//查找逻辑
//定义遍历指针从头结点出发
NodePtr q = L;
for (int i = 0; i < pos; i++)
{
q = q->next;
}
return q; //将找到的结点地址返回
}
//任意位置插入元素
int List_inset_pos(NodePtr L, int pos, datatype e)
{
//判断逻辑
if (NULL == L || pos < 1 || pos >= L->len + 1)
{
printf("插入失败\n");
return -1;
}
//申请结点封装数据
NodePtr p = apply_node(e);
if (NULL == p)
{
return -1;
}
//调用函数查找前驱结点
NodePtr q = list_seaech_pos(L, pos - 1);
//开始头插
p->next = q->next;
q->next = p;
//表的变化
L->len++;
printf("插入成功\n");
return 0;
}
//链表头删
int list_delete_head(NodePtr L)
{
if (NULL == L || list_empty(L))
{
printf("删除失败\n");
return -1;
}
NodePtr p = L->next;
L->next = p->next;
free(p);
p = NULL;
L->len--;
printf("头删成功\n");
return 0;
}
//任意位置删除
int list_delete_pos(NodePtr L, int pos)
{
if (NULL == L || list_empty(L) || pos < 1 || pos > L->len)
{
printf("删除失败\n");
return -1;
}
//找到前驱结点
NodePtr q = list_seaech_pos(L, pos - 1);
//删除逻辑
NodePtr p = q->next; //标记
q->next = p->next; //p->next 孤立
free(p); //释放
p = NULL;
//表的变化
L->len--;
printf("删除成功\n");
return 0;
}
//链表按数查找返回位置
int list_search_value(NodePtr L, datatype e)
{
//判断逻辑
if (NULL == L || list_empty(L))
{
printf("查找失败\n");
return -1;
}
//查找逻辑
//定义一个遍历指针从第一个结点出发
NodePtr q = L->next;
for (int index = 1; index <= L->len; index++)
{
//判断当前结点的值是否为要找的数据
if (q->data == e)
{
return index;
}
q = q->next; //继续向后遍历
}
//程序遍历至此,说明没找到
printf("没找到\n");
return -1;
}
//按位置进行修改
int list_update_pos(NodePtr L, int pos, datatype e)
{
//判断逻辑
if (NULL == L || list_empty(L) || pos < 1 || pos > L->len)
{
printf("修改失败\n");
return -1;
}
//按位置查找并修改
list_seaech_pos(L, pos)->data = e;
printf("修改成功\n");
return 0;
}
//按值进行修改
int list_update_value(NodePtr L, datatype old_e, datatype new_e)
{
if (NULL == L || list_empty(L))
{
printf("修改失败\n");
return -1;
}
//按值查找位置
int res = list_search_value(L, old_e);
if (res == -1)
{
printf("没有要修改的值\n");
return -1;
}
//得到要修改数值的位置res,调用按位置修改函数
list_update_pos(L, res, new_e);
printf("数值修改成功\n");
return 0;
}
//链表翻转
void list_revere(NodePtr L)
{
if (NULL == L || list_empty(L))
{
printf("翻转失败\n");
return;
}
NodePtr H = L->next;
L->next = NULL;
NodePtr p = NULL;
while (H != NULL)
{
p = H;
H = H->next;
p->next = L->next;
L->next = p;
}
printf("翻转成功\n");
}
//链表的排序
Node *list_paixu(Node *L)
{
Node *p, *tail, *next;
int temp;
if (L->next->next == NULL)
return L;
for (p = L->next; p->next != NULL; p = p->next) /*尾指针初始化*/
;
tail = p;
while (tail != L->next->next)
{
for (p = L->next; p->next != tail; p = p->next)
{
next = p->next;
if (p->data > next->data) /*相邻节点比较,数据交换*/
{
temp = p->data;
p->data = next->data;
next->data = temp;
}
}
tail = p; /*p->next == tail,即把tail往前移动一位*/
}
printf("排序成功\n");
return L;
}
//用递归的方法实现链表的翻转
//void list_diguirevere(NodePtr L)
//{
//}
//不会TT
//实现链表的查重
int list_quchong(NodePtr L)
{
if (NULL == L || list_empty(L))
{
printf("链表为空或指针无效\n");
return -1;
}
NodePtr p = L;
while (p->next != NULL)
{
NodePtr q = p;
while (q->next != NULL)
{
if (q->next->data == p->data)
{
NodePtr tmp = q->next;
q->next = tmp->next;
free(tmp);
tmp = NULL;
L->len--;
}
else
{
q = q->next;
}
}
p = p->next;
}
printf("查重成功\n");
return 0;
}
main.c文件
#include "1.h"
int main()
{
//调用函数创建一个链表
NodePtr L = list_create();
if (NULL == L)
{
return -1;
}
//调用头插
list_inset_haed(L, 520);
list_inset_haed(L, 1314);
list_inset_haed(L, 5577);
list_inset_haed(L, 1111);
list_inset_haed(L, 666);
list_inset_haed(L, 666);
list_inset_haed(L, 9999);
list_inset_haed(L, 999);
//链表的遍历
list_show(L);
//任意位置插入元素
List_inset_pos(L, 1, 233);
list_show(L);
//头删
list_delete_head(L);
list_show(L);
//任意删
list_delete_pos(L, 1);
list_show(L);
list_delete_pos(L, 2);
list_show(L);
//按数值查找
int m = list_search_value(L, 5577);
if (m >= 1)
{
printf("您要查找的数据在链表的第%d个位置\n", m);
}
//按位置进行修改
list_update_pos(L, 2, 6666);
list_show(L);
//按数值进行修改
list_update_value(L, 6666, 9999);
list_show(L);
//翻转链表
list_revere(L);
list_show(L);
//链表排序
list_paixu(L);
list_show(L);
//查重
list_quchong(L);
list_show(L);
return 0;
}