1.单链表任意位置修改
2.单链表任意位置查找
3.单链表排序
head.h文件
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int datatype;
typedef struct Node
{
datatype data;
struct Node *next;
}*Linklist;
Linklist bull(Linklist l); //排序
int find_data(int n,Linklist l); //任意位置查找
Linklist amend_data(int n,Linklist l); //任意位置修改
Linklist insert_data(int n,Linklist l,int e); //按位置插入
int Linklist_len(Linklist l); //计算链表元素个数
Linklist delete_real(Linklist l); //尾删
Linklist insert_end(int e,Linklist l); //尾插1.0
Linklist delete_head(Linklist l); //头删
Linklist creat_node(); //申请节点空间
Linklist insert_head(datatype e,Linklist l); //头插
int ouputs(Linklist l); //输出
Linklist insert_tail(datatype e,Linklist rear); //尾插
#endif
test.c文件
#include "head.h"
Linklist creat_node() //申请节点空间
{
Linklist node=(Linklist)malloc(sizeof(struct Node));
if(NULL==node)
return NULL;
node->data=0;
node->next=NULL;
return node;
}
Linklist insert_head(datatype e,Linklist l) //头插
{
Linklist node=creat_node();
if(NULL==node)
return NULL;
node->data=e;
node->next=l;
l=node;
return l;
}
int ouputs(Linklist l) //输出
{
if(NULL==l)
{
return -1;
}
while(l!=NULL)
{
printf("%d ",l->data);
l=l->next;
}
printf("\n");
}
Linklist insert_tail(datatype e,Linklist rear) //尾插
{
Linklist s=creat_node();
if(NULL==s)
return NULL;
s->data=e;
if(rear!=NULL)
rear->next=s;
rear=s;
return rear;
}
Linklist insert_end(int e,Linklist l) //尾插1.0
{
Linklist s=creat_node();
s->data=e;
if(l==NULL)
{
l=s;
}
else
{
Linklist end=l;
while(end->next!=NULL)
{
end=end->next;
}
end->next=s;
}
return l;
}
Linklist delete_head(Linklist l) //头删
{
if(NULL==l)
return l;
if(l->next==NULL)
{
free(l);
l=NULL;
}
else
{
Linklist q=l->next;
l->data=q->data;
l->next=q->next;
free(q);
q=NULL;
}
return l;
}
Linklist delete_real(Linklist l) //尾删
{
if(NULL==l)
return NULL;
else if(l->next==NULL)
{
free(l);
l=NULL;
}
else
{
Linklist p=l;
while(p->next->next!=NULL)
{
p=p->next;
}
free(p->next);
p->next=NULL;
}
return l;
}
int Linklist_len(Linklist l) //计算链表元素个数
{
int count=0;
while(l!=NULL)
{
l=l->next;
count++;
}
return count;
}
Linklist insert_data(int n,Linklist l,int e) //按位置插入
{
//1.判断链表是否为空
//2.判断位置是否合法
int len=Linklist_len(l);
if(NULL==l||n<1||n>len+1)
{
puts("insert error\n");
exit(-1);
}
Linklist p=l;
if(n==len+1)
{
insert_end(e,l);
return l;
}
else
{
for(int i=1;i<n;i++)
{
p=p->next;
}
Linklist s=creat_node();
s->next=p->next;
p->next=s;
s->data=p->data;
p->data=e;
return l;
}
}
Linklist amend_data(int n,Linklist l) //任意位置修改
{
int len=Linklist_len(l);
if(NULL==l||n<1||n>len)
{
printf("insert error\n");
exit(-1);
}
int i;
Linklist p=l;
for(i=1;i<n;i++)
{
p=p->next;
}
printf("please enter the modified data:");
int e;
scanf("%d",&e);
p->data=e;
return l;
}
int find_data(int n,Linklist l) //任意位置查找
{
int len=Linklist_len(l);
if(NULL==l||n<1||n>len)
{
printf("insert error\n");
exit(-1);
}
int i;
Linklist p=l;
for(i=1;i<n;i++)
{
p=p->next;
}
return p->data;
}
Linklist bull(Linklist l) //排序
{
int len=Linklist_len(l);
int arr[len];
int i,j,t;
Linklist p=l;
Linklist q=l;
for(i=0;i<len;i++)
{
arr[i]=p->data;
p=p->next;
}
for(i=1;i<len;i++)
{
for(j=0;j<len-i;j++)
{
if(arr[j]>arr[j+1])
{
t=arr[j];arr[j]=arr[j+1];arr[j+1]=t;
}
}
}
for(i=0;i<len;i++)
{
q->data=arr[i];
q=q->next;
}
return l;
}
main.c文件
#include "head.h"
int main(int argc, const char *argv[])
{
Linklist l=NULL;
int n;
datatype e;
printf("please enter n:");
scanf("%d",&n);
/*for(int i=0;i<n;i++)
{
//头插
printf("please enter elemen:");
scanf("%d",&e);
l=insert_head(e,l);
}*/
for(int i=0;i<n;i++)
{
//尾插
printf("please enter elemen:");
scanf("%d",&e);
l=insert_end(e,l);
}
// delete_head(l);
// l=delete_real(l);
// l=insert_data(l);
/* ouputs(l);
printf("请输入要插入的位置:");
int n1;
scanf("%d",&n1);
printf("please enter elemen:");
scanf("%d",&e);
l=insert_data(n1,l,e);
ouputs(l);
ouputs(l);
printf("请输入要修改的位置:");
int n1;
scanf("%d",&n1);
l=amend_data(n1,l);
ouputs(l);*/
ouputs(l);
// printf("请输入要查找的位置:");
// int n1;
// scanf("%d",&n1);
// printf("%d\n",find_data(n1,l));
l=bull(l);
ouputs(l);
return 0;
}
一、链表
顺序表存在满,适用于数据量较小的情况,顺序表不方便插入和删除操作,那么引出链表。链表不需要预估存储空间,动态分配空间。
1.概念
1.1 链表:线性的链式存储,称为链表
1.2 链表的逻辑结构:线性结构【一对一】
1.3 链式的存储结构:链式存储【逻辑相邻,物理不一定相邻】
1.4 链表分类:单向链表、单向循环链表、双向链表、双向循环链表
1.5 节点
节点:数据域、指针域
1.6 头节点和头指针
1.7 节点的结构体定义
1.8 插入和删除
2.单链表的操作
2.1 单链表创建
/*
* function: 创建一个节点
* @param [ in]
* @param [out]
* @return
*/
Linklist create_node()
{
Linklist node=(Linklist)malloc(sizeof(struct Node));
if(NULL==node)
return NULL;
node->data=0;
node->next=NULL;
return node;//0x10
}
2.2 单链表头插
/*
* function: 头插
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
Linklist insert_head(datatype e,Linklist L)
{
//在堆区创建一个节点
Linklist node=create_node();
node->data=e;
node->next=L;
L=node;
return L;
}
2.3 单链表尾插
/*
* function: 尾插
* @param [ in]
* @param [out]
* @return
*/
Linklist insert_rear(datatype e,Linklist L)
{
//创建一个新节点
Linklist s=create_node();
s->data=e;
if(L==NULL)
{
L=s;
}
else
{
//rear指向最后一个节点的地址
Linklist rear=L;
while(rear->next!=NULL)
{
rear=rear->next;
}
rear->next=s;
}
return L;
}
2.4 单链表头删
/*
* function: 头删除
* @param [ in]
* @param [out]
* @return
*/
Linklist delete_head(Linklist L)
{
//判断链表是否为空
if(NULL==L)
{
return L;
}
if(L->next==NULL)
{
free(L);
L=NULL;
}
else
{
Linklist q=L->next;
L->data=q->data;
L->next=q->next;
free(q);
q=NULL;
}
return L;
}
2.5 单链表尾删
/*
* function: 尾部删除
* @param [ in]
* @param [out]
* @return
*/
Linklist delete_rear(Linklist L)
{
//1,判断链表是否为空
if(NULL==L)
{
return NULL;
}
//2,判断如果链表只有一个节点
else if(L->next==NULL)
{
free(L);
L=NULL;
}
else
{
//3,有多个节点
//循环倒数第二个节点
Linklist second=L;
while(second->next->next!=NULL)
{
second=second->next;
}
free(second->next);
second->next=NULL;
}
return L;
}
2.6 单链表遍历
/*
* function: 循环遍历
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
int output(Linklist L)
{
//判断是否创建
//判断是否为空
if(NULL==L )
{
return -1;
}
while(L!=NULL)
{
printf("%d\t",L->data);
L=L->next;
}
puts("");
}
2.7 单链表任意位置插入
int Len_linklist(Linklist L)
{
int count=0;
while(L!=NULL)
{
count++;
L=L->next;
}
return count;
}
/*
* function: 按位置插入
* @param [ in]
* @param [out]
* @return
*/
Linklist insert_by_pos(int pos,datatype e,Linklist L)
{
//1,判断链表是否为空
//2,判断位置是否合法
int len;
if(NULL==L || pos<1 || pos>(len=Len_linklist(L))+1)
{
puts("insert arror");
return L;
}
//3,插入
Linklist p=L;
if(pos==len+1)
{
insert_rear(e,L);
return L;
}
for(int i=1;i<pos;i++)
{
p=p->next;
}
//在p节点后面插入新节点s
Linklist s=create_node();
s->next=p->next;
p->next=s;
s->data=p->data;
p->data=e;
return L;
}
2.8 单链表任意位置删除
2.9 单链表任意位置修改
参数:查找的位置、链表
思路:
判断链表是否为空
判断位置是否合法
循环找到当前pos位置,
直接重新赋值该节点的数据域
2.10 单链表任意位置查找
参数:查找的位置、链表
思路:
判断链表是否为空
判断位置是否合法
循环找到当前pos位置,
直接输出该节点的数据元素
2.11 单链表任意元素插入
2.12 单链表任意元素删除
2.13 单链表任意元素修改
2.14 单链表任意元素查找
2.15 单链表逆置
2.17 单链表排序
2.18 单链表释放