main.c
#include "head.h"
int main(int argc, const char *argv[])
{
//1表示头节点,0表示普通节点
Linklist L=creat_node(1); //创建头节点
int n;
datatype e;
Linklist rear=L; //定义尾部节点地址,注意初始化
printf("请输入要插入的个数n:");
scanf("%d",&n);
for(int i=0;i<n;i++)
{
printf("请输入要插入的值:");
scanf("%d",&e);
// insert_head(L,e); //链表头插
rear=insert_rear(L,e,rear); //链表尾插
}
output(L); //链表输出
int pos;
datatype key;
printf("请输入要查找的元素:");
scanf("%d",&key);
pos=search_data(L,key);
if(pos==-1) printf("查找失败");
else printf("要查找的元素%d的位置是:%d\n",key,pos);
//单链表按照元素修改
printf("请输入要修改的元素:");
scanf("%d",&key);
printf("请输入要修改的元素值:");
scanf("%d",&e);
update_data(L,key,e);
output(L);
//单链表按照元素插入
printf("请输入要插入的元素:");
scanf("%d",&key);
printf("请输入要插入的元素值:");
scanf("%d",&e);
insert_data(L,key,e);
output(L);
//单链表按照元素插入
printf("请输入要删除的元素:");
scanf("%d",&key);
delete_data(L,key);
output(L)
;
//单链表逆置
printf("逆置后:");
rev(L);
output(L);
return 0;
}
test.c
#include "head.h"
/*
* function: 创建节点
* @param [ in]
* @param [out] 1:表示头节点;0:表示普通节点
* @return 成功返回首地址,失败返回NULL
*/
Linklist creat_node(int flag)
{
Linklist L=(Linklist)malloc(sizeof(struct Node));
if(NULL==L)
{
return NULL;
}
//对L初始化
if(flag==1) L->len=0; //对L节点数据域清空
else if(flag==0) L->data=0;
L->next=NULL; //对L的指针域初始化指向null
return L;
}
/*
* function: 链表头插
* @param [ in] 头结点,插入的值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int insert_head(Linklist L,datatype e)
{
//判断头结点是否创建成功
if(NULL==L)
{
return -1;
}
//2.插入新节点s
Linklist s=creat_node(0);
if(NULL==s) //判断s是否为空
{
return -1;
}
//s的数据域赋值,指针域赋值
s->data=e;
s->next=L->next;
L->next=s;
L->len++;
return 0;
}
/*
* function: 链表的输出
* @param [ in] 链表
* @param [out]
* @return 无
*/
void output(Linklist L)
{
//1.判断链表是否创建成功
//2.判断链表是否为空,L->len==0 || L->next==NULL
if ((NULL==L) || (L->next)==NULL) return;
//3.循环遍历
Linklist p=L;
while(p->next!=NULL)
{
p=p->next;
printf("%d\t",p->data);
}
/* for(int i=0;i<L->len;i++) /依赖于len
{
p=p->next;
printf("%d\t",p->data);
}
*/
putchar(10);
}
/*
* function: 尾插
* @param [ in] 头节点,插入的元素
* @param [out] 尾部节点地址
* @return 成功返回尾部节点地址
*/
Linklist insert_rear(Linklist L,datatype e,Linklist rear)
{
//1.判断头节点是否创建成功
if(NULL==L) return NULL;
//2.在尾部插入新节点s
Linklist s=creat_node(0);
if(s==NULL) return NULL;
s->data=e;
rear->next=s;
rear=s;
L->len++;
return rear;
}
/*
* function: 头删除
* @param [ in] 链表
* @param [out]
* @return 成功返回0;失败返回-1
*/
int delete_head(Linklist L)
{
//判断头节点是否创建成功、
//判断链表是否为空
if((NULL==L) || (NULL==L->next))
{
return -1;
}
//删除L->next
Linklist q=L->next;
L->next=q->next;
free(q);
q=NULL;
L->len--;
return 0;
}
/*
* function: 尾删:尾部删除一个节点
* @param [ in] 链表
* @param [out]
* @return 成功返回0,失败返回-1
*/
int delete_rear(Linklist L)
{
//判断头节点是否创建成功、
//判断链表是否为空
if((NULL==L) || (NULL==L->next))
{
return -1;
}
//尾部删除,先循环到倒数第二个节点L->next-next
Linklist p=L;
while(p->next->next!=NULL) //循环到倒数第二个节点
{
p=p->next;
}
free(p->next); //释放最后一个节点
p->next=NULL;
L->len--;
return 0;
}
/*
* function: 按任意位置插入
* @param [ in]
* @param [out] 链表 位置 插入的值
* @return 成功返回0.失败返回-1;
*/
int insert_pos(Linklist L,int pos,datatype e)
{
//1.判断头节点是否创建成功
//2.判断插入的位置是否合法
if(NULL==L || pos<1 || pos>L->len+1)
{
return -1;
}
//3.在pos位置插入e
Linklist p=L;
Linklist s=creat_node(0); //创建一个要插入的新节点s
for(int i=0;i<pos-1;i++)
{
p=p->next; //p循环到指向pos-1的位置
}
if(s==NULL) return -1;
s->data=e;
s->next=p->next;
p->next=s;
L->len++;
return 0 ;
}
/*
* function: 按照任意位置删除
* @param [ in]
* @param [out] 链表 位置
* @return 成功返回0,失败返回-1
*/
int delete_pos(Linklist L,int pos)
{
//1.判断头节点是否创建成功
//2.判读删除的位置是否合法
if(NULL==L || pos<1 || pos>L->len)
{
printf("删除失败");
return -1;
}
//3.删除pos位置的节点
Linklist p=L;
for(int i=0;i<pos-1;i++) //循环到pos-1的位置
{
p=p->next;
}
//删除p->next的节点
Linklist q=p->next; //定义新的q ?
p->next=q->next; //?
free(q);
q=NULL;
L->len--;
return 0;
}
/*
* function: 按照任意位置查找
* @param [ in]
* @param [out] 链表,位置
* @return 返回值
*/
datatype search_pos(Linklist L,int pos)
{
//判断头节点是否创建成功
//判断位置是否合法
if(NULL==L || pos<1 || pos>L->len)
{
return -1;
}
//找到pos位置
Linklist p=L;
for(int i=0;i<pos;i++)
{
p=p->next;
}
return p->data;
}
/*
* function: 链表按位置修改
* @param [ in] 链表,位置,值
* @param [out]
* @return 成功返回0;失败返回-1
*/
int update_pos(Linklist L,int pos,datatype e)
{
//判断头节点是否创建成功
//判断位置是否合法
if(NULL==L || pos<1 || pos>L->len)
{
return -1;
}
//找到pos位置
Linklist p=L;
for(int i=0;i<pos;i++)
{
p=p->next;
}
p->data=e;
return 0;;
}
/*
* function: 链表通过元素查找
* @param [ in] 链表 查找的值
* @param [out]
* @return 返回位置
*/
int search_data(Linklist L,datatype key)
{
//1.判断头结点是否创建成功、
//2.判断链表是否为空
if(NULL==L || NULL==L->next)
{
return -1;
}
Linklist p=L;
int pos=0;
while(p->next!=NULL)
{
p=p->next;
pos++;
if(p->data==key)
{
return pos;
}
}
return -1;
}
/*
* function: 单链表按照元素修改
* @param [ in] 链表 元素位置 元素值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int update_data(Linklist L,datatype key,datatype e)
{
int pos=search_data(L,key);
if(pos==-1) return -1;
update_pos(L,pos,e);
return 0;
}
/*
* function: 单链表按照元素插入
* @param [ in] 链表 元素位置 元素值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int insert_data(Linklist L,datatype key,datatype e)
{
int pos=search_data(L,key);
if(pos==-1) return -1;
insert_pos(L,pos,e);
return 0;
}
/*
* function: 单链表按照元素删除
* @param [ in] 链表 元素值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int delete_data(Linklist L,datatype key)
{
int pos=search_data(L,key);
if(pos==-1) return -1;
int i=0;
Linklist p=L;
while(p->next!=NULL)
{
i++;
p=p->next;
if(p->data == key)
{
delete_pos(L,i);
i--;
}
}
return 0;
}
/*
* function: 逆置
* @param [ in] 链表
* @param [out]
* @return 无
*/
void rev(Linklist L)
{
//1.判断头结点是否创建成功、
//2.判断链表是否为空
if(NULL==L || NULL==L->next)
{
return;
}
//逆置
Linklist p=L->next; //头插需要保存L,否则后续节点丢失
L->next=NULL;
while(p!=NULL)
{
Linklist t=p; //头插需要保存p,否则后续节点丢失
p=p->next;
t->next=L->next; //头插
L->next=t;
}
}
head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int datatype;
//带头节点结构定义
typedef struct Node
{
//数据域
union{
int len; //头节点的数据域;链表
datatype data; //其他节点的数据域
};
//指针域:指向下一个节点的地址
struct Node *next;
}*Linklist;
Linklist creat_node(int flag); //创建节点
int insert_head(Linklist L,datatype e); //链表头插
Linklist insert_rear(Linklist L,datatype e,Linklist rear);
void output(Linklist L); //链表输出
int delete_head(Linklist L);
int delete_rear(Linklist L);
int delete_pos(Linklist L,int pos);
int insert_pos(Linklist L,int pos,datatype e);
datatype search_pos(Linklist L,int pos);
int search_data(Linklist L,datatype key);
int update_pos(Linklist L,int pos,datatype e);
int update_data(Linklist L,datatype key,datatype e);
int insert_data(Linklist L,datatype key,datatype e);
int delete_data(Linklist L,datatype key);
void rev(Linklist L); //逆置
#endif
运行结果
ubuntu@ubuntu:day4$ gcc *.c
ubuntu@ubuntu:day4$ ./a.out
请输入要插入的个数n:5
请输入要插入的值:22
请输入要插入的值:33
请输入要插入的值:55
请输入要插入的值:11
请输入要插入的值:22
22 33 55 11 22
请输入要查找的元素:22
要查找的元素22的位置是:1
请输入要修改的元素:33
请输入要修改的元素值:99
22 99 55 11 22
请输入要插入的元素:99
请输入要插入的元素值:88
22 88 99 55 11 22
请输入要删除的元素:88
22 99 55 11 22
逆置后:22 11 55 99 22