又优化了一下
12.22回顾
又回顾了一下,优化了一下代码,基础思路没有变,废话不多说,直接上代码
- 创建一个结构体(存一个数字和一个结构体指针)
typedef struct _Link{
int data;
struct _Link *next;
}Link;
- 创建链表
尾插法:
Link* Link_list_tail()//尾插法
{
int number;
printf("输入多个数字添加到链表中,输入q结束\n");
Link *head=(Link*)malloc(sizeof(Link));
head->next=NULL;
Link *tail=head;
while(scanf("%d",&number)==1)
{
Link *p=(Link*)malloc(sizeof(Link));
p->data=number;
p->next=NULL;
tail->next=p;
tail=p;
}
getchar();
printf("OK\n");
return head;
}
头插法:
Link* Link_list_head()//头插法
{
int number;
printf("输入多个数字添加到链表中,输入q结束\n");
Link *head=(Link*)malloc(sizeof(Link));
head->next=NULL;
while(scanf("%d",&number)==1)
{
Link *p=(Link*)malloc(sizeof(Link));
p->data=number;
p->next=head->next;
head->next=p;
}
getchar();
printf("OK\n");
return head;
}
不过头插法输入的数据最后读的时候是反着的
- 查找某一个值k
Link* Find(int k,Link *head)//寻找特殊值
{
Link *p=head->next;
Link *q=head;
while(p)
{
if(p->data==k)
{
printf("Find\n");
break;
}
q=p;
p=p->next;
}
if(!p)
{
printf("Not Find\n");
}
return p;//返回指向关键值的指针
}
- 增加某个数number到第targer个节点
Link* Add(int targer,int number,Link *head)//向某节点插入某个数字
{
int i;
Link *p=head;
for(i=0;i<targer-1&&p;i++)
{
p=p->next;
}
if(p)
{
Link *add=(Link*)malloc(sizeof(Link));
add->data=number;
add->next=p->next;
p->next=add;
printf("OK\n");
}
else
{
printf("NO\n");
}
return p;
}
- 删除某个值k
Link* Del(int k,Link *head)//删除某个值
{
Link *p=head->next;
Link *q=head;
while(p)
{
if(p->data==k)
{
printf("Find\n");
break;
}
q=p;
p=p->next;
}
if(!p)
{
printf("No Find\n");
}
else
{
q->next=p->next;
free(p);
p=NULL;
printf("OK\n");
}
return p;
}
- 链表逆置:
原地逆置:
Link* ReverseLink(Link *head)//原地逆置
{
Link *p=head->next;
Link *q=head;
head->next=NULL;
while(p)
{
q=p;
p=p->next;
q->next=head->next;
head->next=q;
}
printf("OK\n");
return p;
}
递归逆置:
Link* ReverseLink_D(Link *head)//递归逆置
{
if(head->next||head)
{
return head;
}
Link *p=ReverseLink_D(head->next);
Link *t=head->next;
t->next=head;
head->next=NULL;
return p;
}
- 显示链表:
Link* Print(Link *head)//显示链表
{
Link *p=head->next;
if(!p)
{
printf("NO");
}
while(p)
{
printf("%d ",p->data);
p=p->next;
}
putchar('\n');
return p;
}
- 删除所有链表:
Link* Del_all(Link *head)//删除所有链表
{
Link *q=head->next;
Link *p=q->next;
head->next=NULL;
while(p)
{
free(q);
q=p;
p=p->next;
}
q=NULL;
p=NULL;
printf("OK\n");
return NULL;
}
下面是全部代码示意图:
#include <stdio.h>
#include <stdlib.h>
typedef struct _Link{
int data;
struct _Link *next;
}Link;
Link* Link_list_tail()//尾插法
{
int number;
printf("输入多个数字添加到链表中,输入q结束\n");
Link *head=(Link*)malloc(sizeof(Link));
head->next=NULL;
Link *tail=head;
while(scanf("%d",&number)==1)
{
Link *p=(Link*)malloc(sizeof(Link));
p->data=number;
p->next=NULL;
tail->next=p;
tail=p;
}
getchar();
printf("OK\n");
return head;
}
Link* Link_list_head()//头插法
{
int number;
printf("输入多个数字添加到链表中,输入q结束\n");
Link *head=(Link*)malloc(sizeof(Link));
head->next=NULL;
while(scanf("%d",&number)==1)
{
Link *p=(Link*)malloc(sizeof(Link));
p->data=number;
p->next=head->next;
head->next=p;
}
getchar();
printf("OK\n");
return head;
}
Link* Find(int k,Link *head)//寻找特殊值
{
Link *p=head->next;
Link *q=head;
while(p)
{
if(p->data==k)
{
printf("Find\n");
break;
}
q=p;
p=p->next;
}
if(!p)
{
printf("Not Find\n");
}
return p;//返回指向关键值的指针
}
Link* Add(int targer,int number,Link *head)//向某节点插入某个数字
{
int i;
Link *p=head;
for(i=0;i<targer-1&&p;i++)
{
p=p->next;
}
if(p)
{
Link *add=(Link*)malloc(sizeof(Link));
add->data=number;
add->next=p->next;
p->next=add;
printf("OK\n");
}
else
{
printf("NO\n");
}
return p;
}
Link* Del(int k,Link *head)//删除某个值
{
Link *p=head->next;
Link *q=head;
while(p)
{
if(p->data==k)
{
printf("Find\n");
break;
}
q=p;
p=p->next;
}
if(!p)
{
printf("No Find\n");
}
else
{
q->next=p->next;
free(p);
p=NULL;
printf("OK\n");
}
return p;
}
Link* Del_all(Link *head)//删除所有链表
{
Link *q=head->next;
Link *p=q->next;
head->next=NULL;
while(p)
{
free(q);
q=p;
p=p->next;
}
q=NULL;
p=NULL;
printf("OK\n");
return NULL;
}
Link* ReverseLink(Link *head)//原地逆置
{
Link *p=head->next;
Link *q=head;
head->next=NULL;
while(p)
{
q=p;
p=p->next;
q->next=head->next;
head->next=q;
}
printf("OK\n");
return p;
}
Link* ReverseLink_D(Link *head)//递归逆置
{
if(head->next||head)
{
return head;
}
Link *p=ReverseLink_D(head->next);
Link *t=head->next;
t->next=head;
head->next=NULL;
return p;
}
Link* Print(Link *head)//显示链表
{
Link *p=head->next;
if(!p)
{
printf("NO");
}
while(p)
{
printf("%d ",p->data);
p=p->next;
}
putchar('\n');
return p;
}
int main()
{
Link *head=(Link*)malloc(sizeof(Link));
head->next=NULL;
while(1){
printf("输入1创建链表\n");
printf("输入2查找某值\n");
printf("输入3插入某数到某个节点\n");
printf("输入4删除某值\n");
printf("输入5逆置链表\n");
printf("输入6显示链表\n");
printf("输入7删除整个链表\n");
printf("输入0结束程序\n");
int n;
scanf("%d",&n);
if(n==0)
{
break;
}
switch (n){
case 1:
head=Link_list_tail();
break;
case 2:
printf("输入需要查找的值\n");
int k;
scanf("%d",&k);
Find(k,head);
break;
case 3:
printf("输入要插入的节点序号和要插入的值\n");
int targer,number;
scanf("%d%d",&targer,&number);
Add(targer,number,head);
break;
case 4:
printf("输入一个数来删除它\n");
int key;
scanf("%d",&key);
Del(key,head);
break;
case 5:
printf("逆置链表\n");
ReverseLink(head);
break;
case 6:
printf("显示链表\n");
Print(head);
break;
case 7:
printf("删除整个链表\n");
Del_all(head);
break;
defult:
break;
}
}
printf("Goodbye!");
getchar();
getchar();
return 0;
}
12.20旧版
- 创建一个结构体(存一个数字和一个结构体指针)
typedef struct _list{
int date;
struct _list *next;
}List;
- 创建链表
尾插法:
List* link_list_tail()//尾插法
{
int number;
printf("输入多个数字添加到链表中,输入q结束\n");
List *head=(List*)malloc(sizeof(List));
head->next=NULL;
List *tail=head;
while(scanf("%d",&number)==1)
{
List *p=(List*)malloc(sizeof(List));
p->date=number;
p->next=NULL;
tail->next=p;
tail=p;
}
getchar();
return head;
}
头插法:
List* link_list_head()//头插法反着的
{
int number;
printf("输入多个数字添加到链表中,输入q结束\n");
List *head=(List*)malloc(sizeof(List));
head->next=NULL;
while(scanf("%d",&number)==1)
{
List *p=(List*)malloc(sizeof(List));
p->date=number;
p->next=head->next;
head->next=p;
}
getchar();
return head;
}
不过头插法输入的数据最后读的时候是反着的
- 查找某一个值k
List* find(int k,List*head)//查找某值
{
List *p=head->next;
List *q=head;
while(p)
{
if(p->date==k)
{
printf("Find\n");
break;
}
q=p;
p=p->next;
}
if(!p)
{
printf("No\n");
}
return q;//返回前一个的指针
}
- 增加某个数number到第targer个节点
List* add(int targer,int number,List*head)//增加某个数到某个节点
{
int i;
List *p=head;
for(i=0;i<targer-1&&p;i++)
{
p=p->next;//找到它的前一个指针
}
if(p)
{
List *tar=(List*)malloc(sizeof(List));
tar->date=number;
tar->next=p->next;
p->next=tar;
printf("OK\n");
}else
{
printf("No\n");
}
return p;
}
- 删除某个值k
List* del(List *head,int k)//删除某个值
{
List*p=head->next;
List*q=head;
while(p)
{
if(p->date==k){
printf("Find\n");
break;
}
q=p;
p=p->next;
}
if(!p){
printf("No\n");
}else{
p=p->next;
free(q->next);
q->next=p;
printf("OK\n");
}
}
- 链表逆置:
原地逆置:
List* ReverseLink(List *head)//原地逆置
{
List* p=head->next;
List* q=p;
head->next=NULL;
while(p)
{
q=p;
p=p->next;
q->next=head->next;
head->next=q;
}
}
递归逆置:
List* ReverseLink_D(List *head)//递归逆置
{
if(head->next==NULL||head==NULL){
return head;
}//递归结束条件
List *p=ReverseLink_D(head->next);
List *t=head->next;
t->next=head;
head->next==NULL;
return p;
}
- 显示链表:
List* print(List*head)//显示链表
{
List*p=NULL;
if(head->next){
p=head->next;
}else{
printf("NO\n");
return NULL;
}
while(p)
{
printf("%d ",p->date);
p=p->next;
}
putchar('\n');
return head;
}
- 删除所有链表:
List* del_all(List*head)//删除所有链表
{
List*p=head->next->next;
List*q=head->next;
head->next=NULL;
for(;p;q=p,p=p->next)
{
free(q);
}
printf("OK\n");
}
- 最后综合一下(可以把上述内容放到一个文件里面调用更方便)
#include<stdio.h>
#include<stdlib.h>
typedef struct _list{
int date;
struct _list *next;
}List;
List* link_list_tail()//尾插法
{
int number;
printf("输入多个数字添加到链表中,输入q结束\n");
List *head=(List*)malloc(sizeof(List));
head->next=NULL;
List *tail=head;
while(scanf("%d",&number)==1)
{
List *p=(List*)malloc(sizeof(List));
p->date=number;
p->next=NULL;
tail->next=p;
tail=p;
}
getchar();
return head;
}
List* link_list_head()//头插法反着的
{
int number;
printf("输入多个数字添加到链表中,输入q结束\n");
List *head=(List*)malloc(sizeof(List));
head->next=NULL;
while(scanf("%d",&number)==1)
{
List *p=(List*)malloc(sizeof(List));
p->date=number;
p->next=head->next;
head->next=p;
}
getchar();
return head;
}
List* find(int k,List*head)//查找某值
{
List *p=head->next;
List *q=head;
while(p)
{
if(p->date==k)
{
printf("Find\n");
break;
}
q=p;
p=p->next;
}
if(!p)
{
printf("No\n");
}
return q;//返回前一个的指针
}
List* add(int targer,int number,List*head)//增加某个数到某个节点
{
int i;
List *p=head;
for(i=0;i<targer-1&&p;i++)
{
p=p->next;//找到它的前一个指针
}
if(p)
{
List *tar=(List*)malloc(sizeof(List));
tar->date=number;
tar->next=p->next;
p->next=tar;
printf("OK\n");
}else
{
printf("No\n");
}
return p;
}
List* del(List *head,int k)//删除某个值
{
List*p=head->next;
List*q=head;
while(p)
{
if(p->date==k){
printf("Find\n");
break;
}
q=p;
p=p->next;
}
if(!p){
printf("No\n");
}else{
p=p->next;
free(q->next);
q->next=p;
printf("OK\n");
}
}
List* del_all(List*head)//删除所有链表
{
List*p=head->next->next;
List*q=head->next;
head->next=NULL;
for(;p;q=p,p=p->next)
{
free(q);
}
printf("OK\n");
}
List* ReverseLink(List *head)//原地逆置
{
List* p=head->next;
List* q=p;
head->next=NULL;
while(p)
{
q=p;
p=p->next;
q->next=head->next;
head->next=q;
}
}
List* ReverseLink_D(List *head)//递归逆置
{
if(head->next==NULL||head==NULL){
return head;
}//递归结束条件
List *p=ReverseLink_D(head->next);
List *t=head->next;
t->next=head;
head->next==NULL;
return p;
}
List* print(List*head)//显示链表
{
List*p=NULL;
if(head->next){
p=head->next;
}else{
printf("NO\n");
return NULL;
}
while(p)
{
printf("%d ",p->date);
p=p->next;
}
putchar('\n');
return head;
}
int main()
{
List*head=NULL;
while(1){
printf("输入1创建链表\n");
printf("输入2查找某值\n");
printf("输入3插入某数到某个节点\n");
printf("输入4删除某值\n");
printf("输入5逆置链表\n");
printf("输入6显示链表\n");
printf("输入7删除整个链表\n");
printf("输入0结束程序\n");
int n;
scanf("%d",&n);
if(n==0)
{
break;
}
switch (n){
case 1:
head=link_list_tail();
break;
case 2:
printf("输入需要查找的值\n");
int k;
scanf("%d",&k);
List*p=find(k,head);
break;
case 3:
printf("输入要插入的节点序号和要插入的值\n");
int targer,number;
scanf("%d%d",&targer,&number);
add(targer,number,head);
break;
case 4:
printf("输入一个数来删除它\n");
int key;
scanf("%d",&key);
del(head,key);
break;
case 5:
printf("逆置链表\n");
ReverseLink(head);
break;
case 6:
printf("显示链表\n");
print(head);
break;
case 7:
printf("删除整个链表\n");
del_all(head);
break;
defult:
break;
}
}
return 0;
}
- 运行结果:
创建一个链表:
查找链表中是否存在某个值:
插入某数到某个节点:
删除链表中的一个值:
逆置链表:
删除整个链表:
结束程序: