思维导图:
main.c:
#include "head.h"
void menue()
{
puts("****************");
puts("\t1,单项链表头插");
puts("\t2,单项链表遍历");
puts("\t3,单项链表尾插");
puts("\t4,单向链表头删");
puts("\t5,单向链表尾删");
puts("\t6,单向链表按下表插入");
puts("\t7,单向链表按下表删除");
puts("\t8,单向链表按下表修改");
puts("\t9,单向链表按下表查找");
puts("\t10,单链表按元素查找");
puts("\t11,单链表按元素插入");
puts("\t12,单链表按元素删除");
puts("\t13,单链表按元素修改");
puts("\t14,单链表排序");
puts("\t15,单链表逆置");
puts("\t16,单链表释放空间");
puts("\t0,结束程序");
puts("****************");
}
int main(int argc, const char *argv[])
{
menue();
int number;
linklist L = create(1);
while(1)
{
printf("\n请输入您的选择:");
scanf("%d",&number);
switch(number)
{
case 1:{
datatype e;
printf("请输入你要插入的数据:");
scanf("%d",&e);
insert_head(L,e);
}break;
case 2:{
output(L);
}break;
case 3:{
datatype e;
printf("请输入你要插入的数据:");
scanf("%d",&e);
insert_rear(L,e);
}break;
case 4:{
delete_head(L);
}break;
case 5:{
delete_rear(L);
}break;
case 6:{
int n;
datatype e;
printf("请输入你要插入的数据:");
scanf("%d",&e);
printf("请输入你要插入的位置:");
scanf("%d",&n);
insert_sub(L,n,e);
}break;
case 7:{
int n;
datatype e;
printf("请输入你要删除的数据位置:");
scanf("%d",&n);
delete_sub(L,n);
}break;
case 8:{
int n;
datatype e;
printf("请输入你要修改的数据位置:");
scanf("%d",&n);
printf("请输入你要修改的值:");
scanf("%d",&e);
updata_sub(L,n,e);
}break;
case 9:{
int n;
printf("请输入你要查找的数据位置:");
scanf("%d",&n);
find_sub(L,n);
}break;
case 10:{
datatype e;
printf("请输入查找的元素:");
scanf("%d",&e);
find_data(L,e);
}break;
case 11:{
datatype e;
printf("请输入插入位置的元素:");
scanf("%d",&e);
insert_data(L,e);
}break;
case 12:{
datatype e;
printf("请输入删除位置的元素:");
scanf("%d",&e);
delete_data(L,e);
}break;
case 13:{
datatype e,new;
printf("请输入修改位置的元素:");
scanf("%d",&e);
printf("请输入修改的的元素:");
scanf("%d",&new);
updata_data(L,e,new);
}break;
case 14:{
bubble(L);
}break;
case 15:{
reverse(L);
}break;
case 16:{
L = free_space(L);
L = NULL;
}break;
default:printf("输入错误,请重新输入\n");break;
case 0:printf("退出程序\n");exit(0);
}
}
return 0;
}
head.h
#ifndef Head_H
#define Head_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int datatype;
typedef struct Node
{
//数据域
union{
int len;//头结点的数据域
datatype data;//其他结点的数据域
};
//指针域
struct Node *next;
}*linklist;
linklist create(int flag);
int insert_head(linklist L,datatype e);
int insert_rear(linklist L,datatype e);
void output(linklist L);
int delete_head(linklist L);
int delete_rear(linklist L);
int insert_sub(linklist L,int n,datatype e);
int delete_sub(linklist L,int n);
int updata_sub(linklist L,int n,datatype e);
int find_sub(linklist L,int n);
int find_data(linklist L,datatype e);
int insert_data(linklist L,datatype e);
int delete_data(linklist L,datatype e);
int updata_data(linklist L,datatype e,datatype new);
void bubble(linklist L);
int reverse(linklist L);
linklist free_space(linklist L);
#endif
test.c
#include "head.h"
/*
* function: 创建结点
* @param [ in]
* @param [out]
* @return 成功返回地址 失败返回NULL
*/
linklist create(int flag)
{
//创建结点
linklist L = (linklist)malloc(sizeof(struct Node));
//创建失败
if(L==NULL)
return NULL;
//对头结点初始化
if(flag==1)
L->len = 0;
//普通结点
else if(flag==0)
L->data = 0;
//对结点的指针进行初始化
L->next = NULL;
return L;
}
/*
* function: 头插
* @param [ in] 链表 插入的值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int insert_head(linklist L,datatype e)
{
//判断链表是否创建
if(L==NULL){
printf("头插失败\n");
return -1;
}
//头插
//创建新结点s
linklist s = create(0);
if(s==NULL){
printf("头插失败\n");
return-1;
}
//s的数据域赋值
s->data = e;
//连接s进单链表
s->next = L->next;
L->next = s;
//单链表长度增加
L->len++;
return 0;
}
/*
* function: 单链表的尾插
* @param [ in] 单链表 插入的值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int insert_rear(linklist L,datatype e)
{
//判断单链表是否创建
if(L==NULL){
printf("尾插失败\n");
return -1;
}
//循环到尾结点
linklist p = L;
while(p->next!=NULL)
p = p->next;
//在最后一个结点前面插入s
linklist s = create(0);
if(s==NULL){
printf("尾插失败\n");
return -1;
}
//数据域赋值
s->data = e;
//连接s
p->next = s;
L->len++;
return 0;
}
/*
* function: 单链表的遍历
* @param [ in] 单链表
* @param [out]
* @return 无
*/
void output(linklist L)
{
//判断单链表是否创建
//判断单链表是否为空
if(L==NULL||L->len==0)
printf("遍历失败\n");
//遍历
linklist p = L;
for(int i = 0;i<L->len;i++){
p=p->next;//后移
printf("%d\t",p->data);
}
puts("");
}
/*
* function: 单链表的头删
* @param [ in] 单链表
* @param [out]
* @return 成功返回0,失败返回-1
*/
int delete_head(linklist L)
{
//判断单链表是否创建
//判断单链表是否为空
if(L==NULL||L->len==0){
printf("删除失败\n");
return -1;
}
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(L==NULL||L->len==0){
printf("删除失败\n");
return -1;
}
linklist p = L;
//循环到倒数第二个
while(p->next->next!=NULL)
p = p->next;
linklist q = p->next;
p->next = NULL;
free(q);
q = NULL;
L->len--;
return 0;
}
/*
* function: 按下标插入
* @param [ in] 单链表 插入位置 插入的值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int insert_sub(linklist L,int n,datatype e)
{
//判断单链表是否创建
//判断位置是否合法
if(L==NULL||n<1||n>L->len+1){
printf("插入失败\n");
return -1;
}
//循环到插入位置的前一个
linklist p = L;
for(int i = 0;i<n-1;i++){
p = p->next;
}
//创建新结点
linklist s = create(0);
if(s==NULL)
return -1;
//s的数据域赋值
s->data = e;
//连接s
s->next = p->next;
p->next = s;
L->len++;
return 0;
}
/*
* function: 单链表按位置删除
* @param [ in] 单链表 位置
* @param [out]
* @return 成功返回0,失败返回-1
*/
int delete_sub(linklist L,int n)
{
//判断单链表是否创建
//判断单链表是否为空
//判断位置是否合法
if(L==NULL||L->len==0||n<1||n>L->len){
printf("删除失败\n");
return -1;
}
//循环到删除位置的前一个,用p指向
linklist p = L;
for(int i = 0;i<n-1;i++){
p = p->next;
}
//用q指向删除位置
linklist q = p->next;
//从单链表取出q
p->next = q->next;
free(q);
q = NULL;
L->len--;
return 0;
}
/*
* function: 单链表按位置修改
* @param [ in] 单链表 位置 修改的值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int updata_sub(linklist L,int n,datatype e)
{
//判断单链表是否创建
//判断单链表是否为空
//判断位置是否合法
if(L==NULL||L->len==0||n<1||n>L->len){
printf("修改失败\n");
return -1;
}
//循环到修改位置,用p指向
linklist p = L;
for(int i = 0;i<n;i++)
p = p->next;
//修改p的数据域
p->data = e;
return 0;
}
/*
* function: 单链表按位置查找
* @param [ in] 单链表 位置
* @param [out]
* @return 成功返回0,失败返回-1
*/
int find_sub(linklist L,int n)
{
//判断单链表是否创建
//判断单链表是否为空
//判断位置是否合法
if(L==NULL||L->len==0||n<1||n>L->len){
printf("查找失败\n");
return -1;
}
//循环到查找位置,用p指向
linklist p = L;
for(int i = 0;i<n;i++){
p = p->next;
}
printf("查找的值是:%d\n",p->data);
return 0;
}
/*
* function: 单链表的按元素查找
* @param [ in] 链表 查找的值
* @param [out]
* @return 成功返回位置,失败返回-1
*/
int find_data(linklist L,datatype e)
{
//判断单链表是否创建
//判断单链表是否为空
if(L==NULL||L->len==0){
printf("查找失败\n");
return -1;
}
int sub = 0;
linklist p = L;
while(p->next!=NULL){
p = p->next;
sub++;
if(p->data==e){
return sub;
}
}
return -1;
}
/*
* function: 单链表的按元素插入
* @param [ in] 单链表 插入位置元素的值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int insert_data(linklist L,datatype e)
{
//根据e查找位置
int sub = find_data(L,e);
if(sub==-1)
return -1;
insert_sub(L,sub,e);
return 0;
}
/*
* function: 单链表的按元素删除
* @param [ in] 单链表 删除位置元素的值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int delete_data(linklist L,datatype e)
{
//根据e查找位置
int sub = find_data(L,e);
if(sub==-1)
return -1;
delete_sub(L,sub);
return 0;
}
/*
* function: 单链表的按元素修改
* @param [ in] 单链表 修改前元素的值 修改后元素的值
* @param [out]
* @return 成功返回0,失败返回-1
*/
int updata_data(linklist L,datatype e,datatype new)
{
//根据e查找位置
int sub = find_data(L,e);
if(sub==-1)
return -1;
updata_sub(L,sub,new);
return 0;
}
/*
* function: 冒泡排序
* @param [ in] 链表
* @param [out]
* @return 无
*/
void bubble(linklist L)
{
//1,判断链表是否创建
//2,判断链表是否为空
if(L==NULL || L->next==NULL)
{
printf("排序失败\n");
}
//3,冒泡排序
for(linklist i=L->next;i->next!=NULL;i=i->next)
{
int count=0;
for(linklist j=L->next;j->next!=NULL;j=j->next)
{
if(j->data>j->next->data)
{
datatype t=j->data;
j->data=j->next->data;
j->next->data=t;
count++;
}
}
if(count==0)
break;
}
}
/*
* function: 单链表的逆置
* @param [ in] 单链表
* @param [out]
* @return 成功返回0,失败返回-1
*/
int reverse(linklist L)
{
//判断单链表是否创建
//判断单链表是否为空
if(L==NULL||L->len==0)
return -1;
//工作指针p从头结点后一个元素开始指向
linklist p = L->next;
//断开头节点
L->next = NULL;
while(p!=NULL){
//工作指针t指向p,p向后移动
linklist t = p;
p = p->next;
//头插t
t->next = L->next;
L->next = t;
}
return 0;
}
/*
* function: 单链表释放空间
* @param [ in] 单链表
* @param [out]
* @return 返回L
*/
linklist free_space(linklist L)
{
if(L==NULL)
return NULL;
int n = L->len;
for(int i = 0;i<n;i++)
delete_head(L);
free(L);
L = NULL;
return L;
}