栈 郝斌老师-数据结构

版权声明:本文为博主原创文章,未经博主允许不得转载! https://blog.csdn.net/weixin_42839965/article/details/81747363

栈的初始化

//pTop和pBottom直面是垃圾值,只有当两者同时指向一个没事实际含义的头结点时才造出一个空栈
void init(PSTACK pS)//将init(&S)中S的地址赋给pS
{
	pS->pTop = (PNODE)malloc(sizeof(NODE));
	if (NULL == pS->pTop)
	{
		printf("动态内存分配失败!\n");
		exit(-1);
	}
	else//动态内存分配成功,将新的节点的地址存储在了pS->pTop
	{
		pS->pBottom = pS->pTop;
		pS->pTop->Next = NULL;//pS->pBottom->Next=NULL;
	//将新节点的指针域清空
	}
	
}

压栈:
压栈都是压入当前栈顶的上方
这里写图片描述

/压栈
void push(PSTACK pS, int val)
{
	PNODE pNew = (PNODE)malloc(sizeof(NODE));//导致新的节点
	pNew->data = val; //把val的值赋给新节点的数据域

	//新的节点的指针域要指向
	pNew->Next = pS->pTop;//pS->pTop不能改成pBottom
	pS->pTop = pNew;//新节点的指针域放到pS->pTop

	return;
}

出栈:
这里写图片描述
直接将pS->pBotoom的值赋给pS->pTop会使得中间的节点无法找找到,造成内存泄漏,所以这个方法不行;
解决方法:先定义两个指针p和q,指针p指向栈顶,q指向p的下一个节点这里写图片描述

//出栈,把pS所指向的栈出栈一次,并把出栈的元素存入pVal形参所指向的变量中,若出栈失败返回false,否则返回true
bool pop(PSTACK pS, int *pVal)
{
	if (empty(pS))//pS本身存放的就是地址
	{
		return false;
	}
	else
	{
		PNODE r = pS->pTop;
		*pVal = r->data;
		pS->pTop=r->Next;
		free(r);
		r = NULL;

		return true;
	}
}

附 全部代码:

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

typedef struct Node
{
	int data;
	struct Node *Next;
}NODE,*PNODE;

typedef struct Stack
{
	PNODE pTop;//永远指向栈顶的位置
	PNODE pBottom;//永远指向的是栈顶元素的下一个没有实际含义的元素
}STACK,*PSTACK;//PSTACK等价于struct STACK *

void init(PSTACK);//PSTACK是指针,改变实参STACK S的值
void push(PSTACK, int);
void traverse(PSTACK);
bool pop(PSTACK, int *);//出栈
void clear(PSTACK pS);//清空

int main(void)
{
	STACK S;//STACK等价于struct Stack,变量S中含有ptop和pbottom两个成员
	int val;
	
	init(&S);//目的是造出空栈
	//栈初始化,子函数调用,S无法改变变量STACK S的值,所以必须取地址,取地址用指针
	
	//链表不会溢出,所以不需要返回值
	push(&S,1);//压栈,只能从栈顶进行操作,无法指定插入的位置
	push(&S,2);
	push(&S,33);
	push(&S,24);
	push(&S,62);
	push(&S,12);
	traverse(&S);//遍历输出
	printf("\n");

	clear(&S);
	traverse(&S);//遍历输出
	printf("\n");

	//出栈有可能会失败,所以需要返回值
	if (pop(&S, &val))//将出栈的元素的值存储在val中
	{
		printf("出栈成功,出栈的元素是%d\n", val);
	}
	else
		printf("出栈失败!\n");
	traverse(&S);//遍历输出
	
	return 0;
}

//初始化,造成空栈
//pTop和pBottom直面是垃圾值,只有当两者同时指向一个没事实际含义的头结点时才造出一个空栈
void init(PSTACK pS)//将init(&S)中S的地址赋给pS
{
	pS->pTop = (PNODE)malloc(sizeof(NODE));
	if (NULL == pS->pTop)
	{
		printf("动态内存分配失败!\n");
		exit(-1);
	}
	else//动态内存分配成功,将新的节点的地址存储在了pS->pTop
	{
		pS->pBottom = pS->pTop;
		pS->pTop->Next = NULL;//pS->pBottom->Next=NULL;
	//将新节点的指针域清空
	}
	
}

//压栈
void push(PSTACK pS, int val)
{
	PNODE pNew = (PNODE)malloc(sizeof(NODE));//导致新的节点
	pNew->data = val; //把val的值赋给新节点的数据域

	//新的节点的指针域要指向
	pNew->Next = pS->pTop;//pS->pTop不能改成pBottom
	pS->pTop = pNew;//新节点的指针域放到pS->pTop

	return;
}

//遍历输出,对栈遍历,输出栈顶和栈底,但是栈顶和栈底全部都在S里面,所以只需要;一个形参
//先定义一个指针P,永远指向栈顶元素,以次输出,直到P=pBottom结束
void traverse(PSTACK pS)
{
	PNODE p = pS->pTop;
	while (p!=pS->pBottom)
	{
		printf("%d ", p->data);
		p = p->Next;
	}
	return;
}
bool empty(PSTACK pS)
{
	if (pS->pBottom == pS->pTop)
		return true;
	else
		return false;
}

//出栈,把pS所指向的栈出栈一次,并把出栈的元素存入pVal形参所指向的变量中,若出栈失败返回false,否则返回true
bool pop(PSTACK pS, int *pVal)
{
	if (empty(pS))//pS本身存放的就是地址
	{
		return false;
	}
	else
	{
		PNODE r = pS->pTop;
		*pVal = r->data;
		pS->pTop=r->Next;
		free(r);
		r = NULL;

		return true;
	}
}

//
void clear(PSTACK pS)
{
	if (empty(pS))
		return;
	else
	{
		PNODE p = pS->pTop;
		PNODE q = NULL;
		while (q != pS->pBottom)
		{
			q = p->Next;
			free(p);
			p = q;
		}
		pS->pTop = pS->pBottom;
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_42839965/article/details/81747363
今日推荐