1> 将链表的相关操作自己手动完成一下
链表的排序
链表的反转(递归实现)
链表去重
link.h
#ifndef LINK_H
#define LINK_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_insert_head(NodePtr L,datatype e);
//链表遍历函数
int list_show(NodePtr L);
//通过位置查找节点
NodePtr list_search_pos(NodePtr L,int pos);
//任意位置插入
int list_insert_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,datatype new);
//将链表进行翻转
void list_reverse(NodePtr L);
//释放链表
void list_destroy(NodePtr L);
//升序
void list_sort(NodePtr L);
//递归翻转
NodePtr reverse(NodePtr L);
//去重
int unique(NodePtr L);
#endif
link.c
#include"link.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_insert_head(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("链表中的元素分别是:");
//遍历逻辑
NodePtr q =L->next;//定义遍历指针从第一个节点出发
while(q)
{
//输出数据域
printf("%d\t",q->data);
q=q->next;//指针向后偏移一个
}
printf("\n");
return 0;
}
//通过位置查找节点
NodePtr list_search_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_insert_pos(NodePtr L,int pos,datatype e)
{
//判断逻辑
if(NULL==L||list_empty(L)||pos<1||pos>L->len+1)
{
printf("插入失败\n");
return -1;
}
//申请节点封装数据
NodePtr p = apply_node(e);
if(NULL==p)
{
return -1;
}
//调用函数查找前驱节点
NodePtr q = list_search_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_search_pos(L,pos-1);
//删除逻辑
NodePtr p = q->next;
q->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;
}
//按位置查找逻辑
NodePtr p = list_search_pos(L,pos);
//修改逻辑
p->data=e;
printf("修改成功\n");
return 0;
}
//链表按值进行修改
int list_update_value(NodePtr L,datatype old,datatype new)
{
//判断逻辑
if(NULL==L||list_empty(L))
{
printf("修改失败\n");
return -1;
}
//按值查找位置
int res = list_search_value(L,old);
if(res == -1)
{
printf("没有要修改的值\n");
return -1;
}
//按位置修改
list_update_pos(L,res,new);
printf("修改成功\n");
return 0;
}
//将链表进行翻转
void list_reverse(NodePtr L)
{
//判断逻辑
if(NULL==L||L->len<=1)
{
printf("翻转失败\n");
return;
}
//翻转逻辑
NodePtr H =L->next;//将链表元素进行托付
L->next=NULL;//自己白手起家
NodePtr p = NULL;//节点的搬运工
while(H!=NULL)
{
p=H;//搬运第一个节点
H=H->next;//头指针后移
//将p以头插的方式放入L中
p->next=L->next;
L->next=p;
}
printf("翻转成功\n");
}
//释放链表
void list_destroy(NodePtr L)
{
if(NULL==L)
{
return;
}
while(!list_empty(L))
{
//头删
list_delete_head(L);
}
//释放头节点
free(L);
L=NULL;
printf("释放成功\n");
}
//升序
void list_sort(NodePtr L)
{
if(NULL==L||list_empty(L))
{
printf("排序失败\n");
return;
}
for(int i=1;i<L->len;i++)
{
NodePtr q=L->next;
for(int j=0;j<L->len-i;j++)
{
if(q->data>q->next->data)
{
datatype t = q->data;
q->data = q->next->data;
q->next->data = t;
}
q=q->next;
}
}
}
//递归翻转
NodePtr reverse(NodePtr L)
{
NodePtr q = L;
if(q->next==NULL)
{
return NULL;
}
while(q!=NULL)
{
q=q->next;
}
q->next=L;
NodePtr p = list_search_pos(q,L->len-1);
p->next=NULL;
}
//去重
int unique(NodePtr L)
{
int res=0;
if(NULL==L||list_empty(L))
{
printf("去重失败\n");
return -1;
}
NodePtr p = L->next;
while(p)
{
NodePtr q=p->next;
while(q)
{
if(p->data==q->data)
{
res = list_search_value(L,q->data);
list_delete_pos(L,res);
}
q=q->next;
}
p=p->next;
}
return 0;
}
main.c
#include"link.h"
int main(int argc, const char *argv[])
{
//调用函数创建一个链表
NodePtr L = list_create();
if(NULL==L)
{
return -1;
}
//调用头插函数
list_insert_head(L,1);
list_insert_head(L,3);
list_insert_head(L,5);
list_insert_head(L,7);
/* list_insert_head(L,666);
list_insert_head(L,666);
list_insert_head(L,666);
list_insert_head(L,666);
list_insert_head(L,666);
list_insert_head(L,666);
list_insert_head(L,666);*/
//调用遍历函数
list_show(L);
/* list_insert_pos(L,4,100);
list_show(L);
list_delete_head(L);
list_show(L);
list_delete_pos(L,L->len);
list_show(L);
int res = list_search_value(L,100);
if(res != -1)
{
printf("您要找的数据在链表的第%d个位置\n",res);
}
list_update_pos(L,1,923);
list_show(L);
list_update_value(L,923,888);
list_show(L);*/
reverse(L);
list_show(L);
/* list_sort(L);
list_show(L);
unique(L);
list_show(L);*/
list_destroy(L);
L=NULL;
return 0;
}