定义:
1.栈是一种先进后出的结构
2.队列是先进先出,如果是用数组实现的话要判断队列是否满,链表的话不存在满的情况
指针用的不多,如果有什么问题或者优化希望可以指点一下。
剩下的都写下代码注释里啦~
注释比较详细,留着下次写的时候可以复习QAQ
/*
下面的栈、队列、链表都是用10个随机生成的数进行的操作
以前写都是用数组写的或者懒一点直接stl,这次用指针写了一次
*/
#include<stdio.h>
#include<string.h>
#include<time.h>
#include<stdlib.h>
#include<math.h>
struct list //封装起来的链表
{
struct tree
{
int node; //权值
tree *next; //储存下一个元素的地址
};
tree *head; //头指针
void init() //初始化链表
{
head=new tree;
head=NULL;
}
void creat() //创建链表
{
tree *p=head;
for(int i=1;i<=10;i++)
{
int t=100+rand()%900; //随机生成10个数用于实验
tree *q; //用于记录中间操作
q=new tree; //分配空间
q->node=t; //赋值
q->next=NULL; //避免野指针
if(i==1) //如果头指针没有元素的话第一个给头指针
head=q;
else
p->next=q; //这里的p记录的是上一个元素的位置
p=q; //p指针向后移动
}
}
void show() //输出链表内的元素
{
tree *p=head; //因为只是输出所以头指针不移动,用p代替移动
int f=0; //这个只是用于判断格式,后面的队列那些就没有写这个了
while(p) //判断链表还有没有元素
{
if(f)
printf(" %d",p->node);
else
{
printf("%d",p->node);
f=1;
}
p=p->next; //p后移
}
printf("\n");
}
int find(int n) //查找n的位置
{
tree *p; //p代替头指针移动
int count=1; //记录当前位置
for(p=head;p;p=p->next)
{
if(p->node==n)
return count;
count++;
}
return -1; //说明链表中不存在n
}
void inset(int ins,int n) //在链表中增加ins元素,并且放在第n个位置
{
tree *p,*q,*o; //p用来代替头指针移动,q记录需要添加的元素,o用来保存添加后的下一个元素的地址
int count=1,flag=0;
for(p=head;p;p=p->next)
{
if(count==ins-1&&p->next!=NULL)
{
flag=1;
q=new tree;
q->node=n;
o=p->next; //o记录下一个元素的地址
p->next=q; //插入
q->next=o; //指向未插入前的下一个地址保证连续
break;
}
else
count++;
}
if(!flag)
printf("can't inset number\n");
else
{
printf("seccess!\n");
show();
}
}
void del(int n) //删除
{
if(find(n)==-1)
printf("don't have this number\n");
else
{
printf("delet success!\n");
tree *p;
for(p=head;p;p=p->next)
{
if(p->next->node==n)
{
p->next=p->next->next; //找到了就直接从第i个指向第i+1个。
break;
}
}
}
show();
}
/*
翻转这里要描述一下
假设现在有一个链表是 A->B->C->D
现在开始翻转 第一步 用一个指针p记录A的位置 指针o记录B的位置,然后A指向空
那么现在就变成了 A o->B->C->D
然后让一个指针 q保存C的地址 然后让o指向A,p移动到o,然后o移动到q
那么就变成了 A<-B o->D
重复上面的步骤就可以完成啦
*/
//递归
/*
当然也可以用递归的方法 假设B C D已经翻转完毕
那么只需要让这个整体指向A就可以了
那递归下去就是 C D已经翻转完毕 只需要指向B就可以了
最里面就是D指向C
*/
void flip() //翻转 这里用的第一种方法
{
tree *p,*q,*o;
p=head;
o=head->next;
head->next=NULL;
while(o)
{
q=o->next;
o->next=p;
p=o;
o=q;
}
head=p;
show();
}
}L;
struct stack //栈
{
struct tree //记录栈内的元素
{
tree * next;
int node;
};
struct Head //记录栈的栈顶
{
tree *top;
int count; //记录栈内有多少元素
};
Head *head; //一如既往头指针
void init() //初始化
{
head=new Head;
head->count=0;
}
void creat() //创建栈
{
for(int i=0;i<10;i++)
{
int x=100+rand()%900; //随机10个数用于实验
tree *p; //记录准备入栈的元素
p=new tree;
p->node=x;
p->next=head->top; //压入栈顶
head->top=p;
(head->count)++;
}
}
void output() //出栈
{
while(head->count)
{
printf("%d ",head->top->node);
head->top=head->top->next; //就像链表删除那样
(head->count)--;
}
printf("\n");
}
}S;
struct Queue //队列
{
struct tree //记录队列元素
{
int node;
tree *next;
};
tree *head,*tail; //头指针和尾指针
void init() //初始化队列
{
head=new tree;
tail=new tree;
head->next=NULL;
tail->next=NULL;
head=tail; //头尾相等相当于空
}
void creat() //创建队列,因为是链式结构所以不存在满的情况
{
for(int i=0;i<10;i++)
{
int x=100+rand()%900;
tree *p;
p=new tree;
p->node=x;
p->next=NULL;
if(head->next==NULL) //先让头有的记录
{
head->next=p;
}
else
{
tail->next=p; //尾记录
}
tail=p; //尾指针后移
}
}
void show() //遍历输出
{
if(head==tail) //判断是否为空
{
printf("Empty!\n");
return;
}
tree * p=head; //因为只是遍历所以不移动头指针
p=p->next;
while(p)
{
printf("%d ",p->node);
p=p->next; //p后移
}
printf("\n");
}
void pop() //出队
{
if(tail==head) //空
{
printf("Empty!\n");
return;
}
head=head->next;
while(head)
{
printf("%d ",head->node);
head=head->next;
}
printf("\n");
tail=head;
}
void flip() //翻转
{
tree *p,*q,*o;
tree *ntail; //记录当前头指针的next
ntail=head->next;
if(head==tail)
{
printf("Empty!\n");
return;
}
p=head->next;
q=p->next;
p->next=NULL;
while(q)
{
o=q->next;
q->next=p;
p=q;
q=o;
}
head->next=p;
tail=ntail;
}
}Q;
int main()
{
//链表
L.init();
srand(time(0));
L.creat();
L.show();
printf("what number do you want to find: ");
int n;
scanf("%d",&n);
int ans=L.find(n);
if(ans==-1)
printf("don't have this number\n");
else
printf("the first number %d at %dth\n",n,ans);
printf("what number do you want to add: ");
scanf("%d",&n);
printf("what position do you want this number inset: ");
int ins;
scanf("%d",&ins);
L.inset(ins,n);
printf("what number do you want to delete: ");
scanf("%d",&n);
L.del(n);
printf("I will flip the list\n");
L.flip();
//栈
S.init();
S.creat();
printf("we get a stack,and now we will print it\n\n");
S.output();
//队列
Q.init();
Q.creat();
printf("we get a queue,and now we will print it\n\n");
Q.show();
Q.flip();
Q.pop();