链表、栈、队列(链式存储结构的添加,删除,查找,翻转 操作)

定义:
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();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值