0
点赞
收藏
分享

微信扫一扫

数据结构(C语言)动态栈的算法实现

文风起武 2022-04-26 阅读 41

首先我们看看什么是栈和动态栈?

栈一种可以实现“先进后出”的存储结构;而动态栈是以链表节点为基本单位的;

第二,动态空栈应该有什么结构?

代码:一个动态栈的结构体需要一个pTop栈顶指针和一个pBottom栈底指针

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

typedef struct Stack{
	PNODE pTop;
	PNODE pBottom;
}STACK,* PSTACK;

 

第三,如何造一个动态空栈?

思路示意图 :

思路:
    1.先创造一个结构体S,S中有栈顶指针和栈底指针
    2.动态创建一个头节点,把头节点的地址赋值给栈底指针和栈顶指针
    3.将头指针的指针域清空

代码:

void init(PSTACK pS){
	pS->pBottom = (PNODE)malloc(sizeof(NODE));
	if(pS->pBottom == NULL){
		printf("动态初始化失败!");
		exit(-1); 
	}
	else{
	pS->pTop = pS->pBottom;
	pS->pBottom->pNext = NULL;
	}
	return;
}

第四、如何给栈的链表结构增添新的节点(压栈)?‘

思路示意图:

 

思路:
    1.动态创建一个新的节点,地址用pNew保存
    2.将新节点和头节点和栈连接一起
        将栈顶底指向新节点,pNew->pNext = pS->pBottom;
        **考虑到节点多了之后应该是将栈顶指向新的节点就行了,因此将pBottom改写成pTop才行**
        将栈顶指向新节点,pS->pTop = pNew;
        

 代码:

void push(PSTACK pS,int val){
	
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	if(pNew == NULL){
		printf("动态初始化失败!");
		exit(-1); 
	}
	pNew->data = val; 

	pNew->pNext = pS->pTop;//可以先理解成 pNew->pNext = pS->pBottom;但是元素多了就不行了 
	pS->pTop = pNew;       
	
	return;
}

再度理解链接的两行代码pNew->pNext = pS->pTop;pS->pTop = pNew;,如图所示:

 

五、如何遍历栈的元素?

思路示意图:

 

思路:
    1.用新的指针p永远指向栈顶,因为只是遍历栈不能够改变栈顶指针,如果改变了栈顶指针我们就找不到遍历完的元素了,所以用一个新的指针。
    2.当p不等于栈底指针的时候,p边向下移动边输出每一个节点的数值域;

代码:

void traverse(PSTACK pS){
	PNODE p = pS->pTop;
	while(p!=pS->pBottom){
		printf("%d\t",p->data);
		p=p->pNext;
	}
	return;
}

六、如何出栈?

思路示意图:

思路:
    1.出栈存在是否出栈成功的清空,如果栈是空栈(栈顶指针==栈底指针),那么就出栈失败,返回false
    2.如果不是空栈,就可出栈了
        应该有一个变量,保存出栈节点的数值域,要实现跨函数改变,就应该输入指针变量给这个函数
    3.创建一个新的指针P保存栈顶指针
    4.栈顶指针指向下一个栈节点
    5.保存出栈节点的数值域
    6.free(p),p = NULL;

 代码:

bool pop(PSTACK pS,int * pVal){
	
	if(empty(pS)){
		return false;
	}else{
		
		PNODE p = pS->pTop;
		pS->pTop = p->pNext;
		*pVal = p->data;
		free(p);
		p = NULL;
		return true;
	}
}
bool empty(PSTACK pS){
	if(pS->pBottom==pS->pTop){
		return true;
	}else{
		return false;
	}
}

七、如何清空栈的节点?

思路示意图: 

思路:
    1.创建两个指针变量p和q
            p保存栈顶指针
            q保存p的指针域
    2.通过一个循环,当p不等于栈底指针   
            free(p)
            p=q
            q=q->pNext
    3.结束循环,将栈顶指针赋值为栈底指针。

 代码:

void clear(PSTACK pS){
	PNODE p = pS->pTop;
	
	while(p!=pS->pBottom){
		PNODE q = p->pNext;
		free(p);
		p=q;
	}
	pS->pTop = pS->pBottom;
	return;
}

主函数代码:

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

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

typedef struct Stack{
	PNODE pTop;
	PNODE pBottom;
}STACK,* PSTACK;

void init(PSTACK pS);
void push(PSTACK pS,int val);
void traverse(PSTACK pS);
bool pop(PSTACK pS,int * pVal);
bool empty(PSTACK pS);
void clear(PSTACK pS);

int main(void){
	STACK S;
	
	init(&S);
	
	push(&S,1);
	push(&S,2);
	push(&S,3);
	push(&S,4);
	push(&S,5);
	push(&S,6);
	
	traverse(&S);
	
	int val;
	if(pop(&S,&val)){
		printf("\n出栈的值是:%d\n",val);
	}else{
		printf("出栈失败!"); 
	}
	traverse(&S);
	
	clear(&S);
	if(pop(&S,&val)){
		printf("\n出栈的值是:%d\n",val);
	}else{
		printf("出栈失败!"); 
	}
	return 0;
}

运行结果:

举报

相关推荐

0 条评论