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++版)

栈的链表实现也有两种,一种是带头结点的链表的实现方式,一种是不带头结点的链表的实现方式。

第一种:(带头结点的栈的实现方式)

基础代码:

#include<stdio.h>
#include<stdlib.h>
#define null NULL 
#define ElemType int
typedef struct LinkStack {
 	ElemType data;
	struct LinkStack *next;  
 }LinkStack; 

栈的初始化:

//初始化
bool initStack(LinkStack **head){
	*head = (LinkStack *)malloc(sizeof(LinkStack));
	if(*head == null){
		return false;
	}
	(*head)->next = null;
	return true;
}

判空:

//判空
bool isEmpty(LinkStack *head){
	return head->next == null;
}

入栈:

//入栈 Push
bool Push(LinkStack *head,ElemType e){
	LinkStack *s = (LinkStack *)malloc(sizeof(LinkStack));
	s->data = e;
	s->next=head->next;
	head->next=s;
	return true;
}

出栈:

//出栈 Pop
bool Pop(LinkStack *head,ElemType &x){
	//判栈空
	if(head->next == null){
		return false; 
	}
	LinkStack *q=head->next;
	x =q->data;
	head->next=q->next;
    free(q);
	return true;
}

获取栈顶元素:

//获取栈顶元素
bool GetTopElem(LinkStack *head,ElemType &x){
	//判空 
	if(head->next == null){
		return false; 
	}
	x=head->next->data;
	return true;
}

栈的删除:

//栈的删除(保留头结点)
bool DeleteStack(LinkStack *head){
	while(head->next!=null){
		LinkStack *q = head->next;
		head->next = q->next;
		free(q);
	}
}

栈的销毁:

//栈的销毁(连头结点一起删除)
bool DestoryStack(LinkStack **head){
	while((*head)->next != null){
		LinkStack *q = (*head)->next;
		(*head)->next = q->next;
		free(q);
	}
	free(*head);
	*head=null; //将main函数中的head指针置为null,避免其成为野指针。
}

栈的打印操作:

//栈的打印操作
void printStack(LinkStack *head){
	while(head->next!=null){
		ElemType data = head->next->data;
		printf("%d\n",data);
		head=head->next;
	}
}

?测试代码及结果:

int main(int argc, char *argv[])
{	 
	LinkStack *head = null;
	//初始化栈
	initStack(&head);
	//判断栈空
	bool flag = isEmpty(head);
	printf("%d\n",flag);	
	//打印栈 
	printStack(head); 
	//入栈
	Push(head,1);
	Push(head,2);
	Push(head,3);
	Push(head,4);
	Push(head,5); 
	//判断栈空
	bool flag1 = isEmpty(head);
	printf("%d\n",flag1); 	
	//打印栈
	printStack(head); 
	//出栈
	ElemType e;
    Pop(head,e);
    //打印栈
	printf("--------------\n");	
	printStack(head);
	Pop(head,e); 	
	printf("--------------\n");	
	printStack(head); 
	Push(head,8); 
	printf("--------------\n");	
	printStack(head); 
	GetTopElem(head,e);
	printf("栈顶元素是%d\n",e);	
	GetTopElem(head,e);
	printf("栈顶元素是%d\n",e);
	//判断栈空
	bool flag2 = isEmpty(head);
	printf("%d\n",flag2); 
	//清空栈 
	DeleteStack(head); 
	//判断栈空
	bool flag3 = isEmpty(head);
	printf("%d\n",flag3); 
	//销毁链表
	 DestoryStack(&head); 
	 if(head == null){
	 	printf("链表销毁成功\n");
 	} 
	return 0;
}

第二种(不带头结点的栈的实现方式):

栈的初始化:

//初始化
bool initStack(LinkStack **head){
	*head = null;
	return true;
}

判空:

//判空
bool isEmpty(LinkStack *head){
	return head==null;
}

入栈:(使用二级指针)

//入栈 Push    //得使用二级指针    //如果使用一级指针,会导致我们每次入栈的时候会在堆内存中创建一个结点,而这个结点随着Push函数调用结束,而长久驻留在堆内存中,这种方式会导致内存泄漏,而main函数中的head指针依然指向的null 
bool Push(LinkStack **head,ElemType e){
	LinkStack *s = (LinkStack *)malloc(sizeof(LinkStack));
	s->data = e;
	//入栈的第一个元素 
	if(*head == null){
	s->next = null;
	*head=s;
	}else{
	//入栈非第一个元素 
		s->next = *head;
		*head=s;		
	}
	return true;
}

出栈:(使用二级指针)

//出栈 Pop   //得用二级指针   //使用一级指针会导致我们释放了q结点之后,main函数中的head指针依然指向q这块未知内存,导致head指针指向了未知位置,成为了野指针,程序不再受控。 
bool Pop(LinkStack **head,ElemType &x){
	//判栈空
	if(*head == null){
		return false; 
	}
	LinkStack *q=*head;
	x =q->data;
	*head=q->next;
	free(q);
	return true;
}

获取栈顶元素:

//获取栈顶元素
bool GetTopElem(LinkStack *head,ElemType &x){
	//判空 
	if(head == null){
		return false; 
	}
	x=head->data;
	return true;
}

栈的销毁:

//栈的销毁
bool DestoryStack(LinkStack **head){
	while(*head != null){
		LinkStack *q = *head;
		*head = q->next;
		free(q);
	}
}

栈的打印:

//栈的打印操作
void printStack(LinkStack *head){
	while(head != null){
		ElemType data = head->data;
		printf("%d\n",data);
		head=head->next;
	}
}

测试代码及结果:

int main(int argc, char *argv[])
{	 
	LinkStack *head;
	
	//初始化栈
	initStack(&head);
	//判断栈空
	bool flag1 = isEmpty(head);
	printf("%d\n",flag1);
	
	//入栈
	Push(&head,1);
	Push(&head,2);
	Push(&head,3);
	Push(&head,4);
	Push(&head,5); 
	
	//判断栈空
	bool flag2 = isEmpty(head);
	printf("%d\n",flag2); 	
	//打印栈
	printf("------------------\n");
	printStack(head); 
		
	//出栈
	ElemType e;
    Pop(&head,e);
    //打印栈
	printf("--------------\n");	
	printStack(head);
	Pop(&head,e); 	
	printf("--------------\n");	
	printStack(head); 
	Push(&head,8); 
	printf("--------------\n");
	printStack(head); 		
	
	//获取栈顶元素 
	GetTopElem(head,e);
	printf("栈顶元素是%d\n",e);	
	GetTopElem(head,e);
	printf("栈顶元素是%d\n",e);

	//判断栈空
	bool flag3 = isEmpty(head);
	printf("%d\n",flag3);  
	//销毁栈 
	DestoryStack(&head);
	
	//判断栈空
	bool flag4 = isEmpty(head);
	printf("%d\n",flag4);  
	 
	if(head == null){
	 	printf("栈销毁成功\n");
 	} 
	return 0;	
}

总结: 栈的链表实现方式中,带头结点的实现方式比不带头结点的实现方式简单、方便。(即第一种方式优于第二种方式)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-04 20:01:20  更:2021-07-04 20:02: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年4日历 -2024/4/23 16:26:49-

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