IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++栈的链式实现方式 -> 正文阅读

[C++知识库]C/C++栈的链式实现方式

个人认为哈,这段代码是最近一个星期写的最完善的代码,如果我没有赋值错的话,应该一丢丢的问题都没错误,美观度其实还可以啦,如果不是单纯依靠函数的话,这个代码美观度可以很高很高

特别注意在151和159这几行代码有很强的复制率,但是我们并没有使用函数,是因为若使用函数我们会发现return?无法停止本层函数,这个是无法避免的重复

特别注意,原来的菜单函数那片一直犯了逻辑错误,导致并不能程序安全退出,这个是目前各种功能最完善的,原来的代码我又去看了一下,我发现我不想动内些代码了,越改越错。

#include<iostream>//内个注意一下下哈,链栈咋能有最大输入量的限制捏,所以不设MAX 
#include<stdlib.h> 
using namespace std;
typedef struct node
{
	int data;
	struct node *next;
}node;
 
typedef struct stack
{
	node *head;//其实我想叫它头指针,那就叫它head吧 
	node *top;//其实这个我还想叫它p,这个这个这个。。。这不就是头插法的指针吗 
	int len;
}stack; 
//注意一下,输出函数时都不要使用引用传递,因为你使用引用传递后会使得指针的指向方向发生变化 !!! 
void  menu(void);
void  caidancaozuo(stack& S,int &jieguo);
void  create(stack &S);//内个在顺序栈中创建的栈中我们设定的是可以直接输入元素的,但是在链栈中这个就算是单纯的初始化吧 
void  pankong(stack &S);//判断栈是否为空栈 
void  clean(stack &S);//个人认为清空和销毁之前创建插入和删除比较好 
void  destroystack(stack &S);
void  outtop(stack S);//输出栈顶元素 
void  charu(stack &S);//插入栈顶元素 
void  deletetop(stack &S);//删除栈顶元素 
void  outstack(stack S);//输出栈的元素 
void  outlen(stack S);//输出栈的长度 
 
int main(void)
{
	stack liststack;
	int jieguo=0;
	menu();
	caidancaozuo(liststack,jieguo);
	if(jieguo==1)
	{
		return 0;
	}
	
} 
void menu(void)       
{                      //很经典的菜单形式 
	char a01[] = "(1)创建栈";
	char a02[] = "(2)判断栈是否为空";
	char a03[] = "(3)清空栈";
	char a04[] = "(4)销毁栈";
	char a05[] = "(5)输出栈顶元素";
	char a06[] = "(6)用于插入栈顶元素";
	char a07[] = "(7)删除栈顶个元素";
	char a08[] = "(8)输出栈中所有元素";
	char a09[] = "(9)输出长度";
	char a10[] = "(10)出入任意不在前面菜单的数字将结束程序";
 
	printf("%-50s", a01);
	printf("%-50s\n", a02);
	printf("%-50s", a03);
	printf("%-50s\n", a04);
	printf("%-50s", a05);
	printf("%-50s\n", a06);
	printf("%-50s", a07);
	printf("%-50s\n", a08);
	printf("%-50s", a09);
	printf("%-50s\n", a10);
}
void caidancaozuo(stack& S,int &jieguo)//再次自我感觉良好觉得这个自我调用也不赖,放前边了 
{
	cout << "请问你想选择哪个指令" << endl;
	int mingling;
	cin >> mingling;
	switch (mingling)
	{
	case 1:
	{
		create(S);
		caidancaozuo(S,jieguo);
		break;
	}
	case 2:
	{
	    pankong(S);
		
		
		caidancaozuo(S,jieguo);
		break;
	}
	case 3:
	{
        clean(S);
		caidancaozuo(S,jieguo);
		break;
	}
	case 4:
	{
	 
       destroystack(S);
	caidancaozuo(S,jieguo);
	break;
	}
	case 5:
	{
		outtop(S);//输出栈顶元素 
		caidancaozuo(S,jieguo);
		break;
	}
	case 6:
	{
		charu(S);//插入栈顶元素 
		caidancaozuo(S,jieguo);
		break;
	}
	case 7:
	{
		deletetop(S);//删除栈顶元素 
		caidancaozuo(S,jieguo);
		break;
	}
	case 8:
	{
		outstack(S);//输出栈的元素 
		caidancaozuo(S,jieguo);
		break;
	}
	case 9:
	{
		outlen(S);//输出栈的长度 
		caidancaozuo(S,jieguo);
		break;
	}
	default:
		if(mingling<=0||mingling>9)
		{
			jieguo=1;
		}
		cout << "您已经决定退出此程序,程序即将退出" << endl;
		break;
	}
}
void  create(stack &S)
{
	S.head=new node;
	//cout<<"头指针是"<<S.head<<endl;       测试使用的 
	S.top=S.head;
	S.head->next=NULL;//防止成为一个野指针(一定不要忘记这点哈) 
	S.len=0;
	if(!S.head)
	{
		cout<<"不知神马原因未能成功创建此栈"<<endl; 
		return;
	}
	cout<<"已成功创建一个链栈"<<endl;
}
void  pankong(stack &S)
{
	if(!S.head)
	{
		cout<<"您还没有创建栈"<<endl;//一个判断是否为空的函数已经把有没有创建都考虑进去了,后期这些只需要调用这一个函数就足够 
		return ;//这个return管不到外边的函数 
	}
	if(S.top==S.head)
	{
		cout<<"此栈是空栈"<<endl;
	}else{
		cout<<"此栈的长度是"<<S.len<<endl; 
	}
}
void  charu(stack &S)//插入栈顶元素 
{
	//此函数其实就是头指针插入时的循环体中的代码 
	if(!S.head)//需要单独的写出来,因为pankong函数的return并不能使得我们的本函数退出,这个是无奈之举,不可封装函数 
	{          
		cout<<"您还没有创建栈,所以怎么操作"<<endl; 
		return ;
	}
	if(S.top==S.head)//特别注意在这几行代码有很强的复制率,大约7行左右,但是我们并没有使用函数,
	{                //是因为若使用函数我们会发现return 无法停止本层函数,这个是无法避免的 
		cout<<"此栈是空栈"<<endl;
	}
	int x;
	cout<<"请输入一个数字"<<endl;
	cin>>x;
	S.top=new node;//切记一定一定要给我们创建的值分配一个合理的位置。 
	S.top->data=x;
	S.top->next=S.head->next;
	S.head->next=S.top; 
	S.len++; 	
}
 
void  clean(stack &S)
{
	if(!S.head)//需要单独的写出来,因为pankong函数的return并不能使得我们的本函数退出,这个是无奈之举,不可封装函数 
	{
		cout<<"您还没有创建栈,所以怎么操作"<<endl; 
		return ;
	}
	if(S.top==S.head)
	{
		cout<<"此栈是空栈"<<endl;
	}
    if(S.len==0)
    {
    	cout<<"您的栈已经是空栈了哈,无需进行清空了"<<endl;
    	return;
	}else{
		
		int a=S.len;//因为后边S.len会发生变化,我们需要提前规避这个风险 
	    for(int i=0;i<a;i++)
	    {
		    node *temp=S.top; 
	        S.top=S.top->next;
	        free(temp); 
	        S.len--;
	    } 
	     
		S.top=S.head=NULL;
		S.len=0;
		cout<<"已经清空您的栈啦"<<endl;
		return;
	}
}
void  deletetop(stack &S)//删除栈顶元素 
{
	//我觉得是不是在删除某个元素时先创建另一个量,使得这个量指向我们需要删除地址空间就好
if(!S.head)//需要单独的写出来,因为pankong函数的return并不能使得我们的本函数退出,这个是无奈之举,不可封装函数 
	{
		cout<<"您还没有创建栈,所以怎么操作"<<endl; 
		return ;
	}
	if(S.top==S.head)
	{
		cout<<"此栈是空栈"<<endl;
	}
	node *temp=S.top; 
	S.top=S.top->next;
	free(temp); 
	S.len--;
    cout<<"栈顶元素已被删除"<<endl;	 
}
void  destroystack(stack &S)//请注意销毁函数和清空函数的区别 
{
	if(!S.head)//需要单独的写出来,因为pankong函数的return并不能使得我们的本函数退出,这个是无奈之举,不可封装函数 
	{
		cout<<"您还没有创建栈,所以怎么操作"<<endl; 
		return ;
	}
	if(S.top==S.head)
	{
		cout<<"此栈是空栈"<<endl;
	}
	int a=S.len;//因为后边S.len会发生变化,我们需要提前规避这个风险 
	for(int i=0;i<a;i++)
	{
		deletetop(S);//删除栈顶元素
	 } 
	free(S.head);//删除后head还是存在head这个指针的,只是我们先前开辟的空间被删除,所以我们输出head还是会有一个地址的
	//我想了好多好多,我发现既然你要传入的是一个执行销毁的函数那么,你是不是实现传递过去了一个你已经创建的栈,
	 //当你进行一系列的操作后,你的指针由指向空变成了一个野指针(当然在不受你管理后) 
	S.head=NULL;
	S.top=NULL;
	S.len=0;
    cout<<"销毁成功"<<endl; //请特别注意清空与销毁函数的区别 
	 
}
void  outtop(stack S)//输出顶嘛 
{
	if(!S.head)//需要单独的写出来,因为pankong函数的return并不能使得我们的本函数退出,这个是无奈之举,不可封装函数 
	{
		cout<<"您还没有创建栈,所以怎么操作"<<endl; 
		return ;
	}
	if(S.top==S.head)
	{
		cout<<"此栈是空栈"<<endl;
	}
	S.head->next=S.top; 
	cout<<"栈顶元素是"<<S.top->data<<endl;
}
void  outstack(stack S)//输出栈的数据 
{
   if(!S.head)//需要单独的写出来,因为pankong函数的return并不能使得我们的本函数退出,这个是无奈之举,不可封装函数 
	{
		cout<<"您还没有创建栈,所以怎么操作"<<endl; 
		return ;
	}
	if(S.top==S.head)
	{
		cout<<"此栈是空栈"<<endl;
	}
	cout<<"您创建的函数是:"<<endl; 
    S.head->next=S.top; 
	for(int i=0;i<S.len;i++)
	{
		cout<<S.top->data<<endl;
		S.top=S.top->next;
	}
}
void  outlen(stack S)//输出长度 
{
    if(!S.head)//需要单独的写出来,因为pankong函数的return并不能使得我们的本函数退出,这个是无奈之举,不可封装函数 
	{
		cout<<"您还没有创建栈,所以怎么操作"<<endl; 
		return ;
	}
	if(S.top==S.head)
	{
		cout<<"此栈是空栈"<<endl;
	}
	 
	cout<<"此栈的长度是"<<S.len<<endl; 
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-16 19:28:07  更:2021-10-16 19:29:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 19:31:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计