1. 程式人生 > >棧的鏈式儲存結構解讀(附詳細程式碼)

棧的鏈式儲存結構解讀(附詳細程式碼)

1 :鏈式儲存結構
  棧的鏈式儲存結構,簡稱鏈棧。
  由於棧只是棧頂在做插入和刪除操作,所以棧頂應該放在單鏈表的頭部。另外,都有了棧頂在頭部了,單鏈表中的頭結點也就失去了意義,通常對於鏈棧來說,是不需要頭結點的。

  對於鏈棧來說,基本不存在棧滿的情況,除非記憶體已經沒有使用空間了。
  對於空棧來說,連結串列原來的定義是頭指標指向空,那麼鏈棧的空其實就是top=NULL。

typedef struct StackNode 
{
	int data;//結點資料域
	struct StackNode* next;//結點指標域
}StackNode,* Linktop;

//鏈棧的資料結構
typedef struct LinkStack 
{
	Linktop top;   //棧頂結點,定義了一個指向上個結構體的指標
	int count;//元素個數
}LinkStack;

2:進棧操作

//壓棧:先將壓入元素放入到連結串列表中,然後再將棧頂指標指向壓入的元素,然後count+1.
int push(LinkStack* stack,int e)
{
	if (!stack)
	{
		return 0;
	}
	StackNode* node = (StackNode*)malloc(sizeof(StackNode));
	node->next = stack->top;           //將元素加入連結串列中
	node->data = e;
	stack->top = node;                 //棧頂元素指向壓入元素
	stack->count++;
	return 1;
}

3:出棧操作

//彈棧:棧頂指標指向要彈出元素前置結點,然後釋放彈出元素記憶體空間,然後count-1
int pop(LinkStack* stack,int *e)
{
	if (!stack && stack->count)
	{
		return	0;
	}
	StackNode* node = stack->top;
	*e = node->data;
	stack->top = node->next;   //棧頂指標指向新的棧頂元素
	free(node);                //釋放元素空間
	stack->count--;
	return 1;
}

具體程式碼實現如下:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

typedef struct StackNode {
	int data;//結點資料域
	struct StackNode* next;//結點指標域
}StackNode,* Linktop;

//鏈棧的資料結構
typedef struct LinkStack {
	Linktop top;   //棧頂結點,定義了一個指向上個結構體的指標
	int count;//元素個數
}LinkStack;

//初始化
int InitLinkStack(LinkStack* stack)
{
	if (!stack)     // 等價於 if(stack == NULL)
	{
		return 0;
	}
	stack->top = NULL;
	stack->count = 0;
	return 1;
}
//清空資料,釋放結點記憶體,實際上就是pop所有資料
int ClearLinkStack(LinkStack* stack)
{
	if (!stack||!stack->count)
	{
		return	0;
	}
	while (stack->count)
	{
		StackNode* node = stack->top;
		stack->top = node->next;
		free(node);
		stack->count--;
	}
	return 1;
}
//判斷鏈棧是否為空
int EmptyLinkStack(LinkStack* stack) 
{
	if (!stack)
	{
		return 0;
	}
	return stack->count == 0 ? 1 : 0;
}
//獲取元素個數
int GetLengthLinkStack(LinkStack* stack)
{
	if (!stack )
	{
		return	-1;
	}
	return stack->count;
}
int GetTop(LinkStack* stack, StackNode** stackNode)
{
	if (!stack)
	{
		return	0;
	}
	*stackNode = stack->top;//將棧頂元素的指標返回,獲取指向可修改棧頂元素內容。
	return 1;
}

//彈棧:棧頂指標指向要彈出元素前置結點,然後釋放彈出元素記憶體空間,然後count-1
int pop(LinkStack* stack,int *e)
{
	if (!stack && stack->count)
	{
		return	0;
	}
	StackNode* node = stack->top;
	*e = node->data;
	stack->top = node->next;   //棧頂指標指向新的棧頂元素
	free(node);                //釋放元素空間
	stack->count--;
	return 1;
}

//壓棧:先將壓入元素放入到連結串列表中,然後再將棧頂指標指向壓入的元素,然後count+1.
int push(LinkStack* stack,int e)
{
	if (!stack)
	{
		return 0;
	}
	StackNode* node = (StackNode*)malloc(sizeof(StackNode));
	node->next = stack->top;           //將元素加入連結串列中
	node->data = e;
	stack->top = node;                 //棧頂元素指向壓入元素
	stack->count++;
	return 1;
}
int PrintfLinkStack(LinkStack* stack)
{
	if (!stack&&stack->count)
	{
		return 0;
	}
	StackNode* node = stack->top;
	while (node)
	{
		printf("%d,", node->data);
		node = node->next;
	}
	puts("");
	return;
}
int main()
{
	LinkStack stack;
	InitLinkStack(&stack);//初始化
	push(&stack, 1);
	push(&stack, 2);
	push(&stack, 3);
	push(&stack, 4);
	push(&stack, 5);
	push(&stack, 6);
	puts("鏈棧元素:");
	PrintfLinkStack(&stack);
	printf("鏈棧元素個數:%d\n", GetLengthLinkStack(&stack));
	int e1,e2,e3;
	pop(&stack, &e1);
	printf("彈出第一個元素:%d\n", e1);
	pop(&stack, &e2);
	printf("彈出第二個元素:%d\n", e2);
	pop(&stack, &e3);
	printf("彈出第二個元素:%d\n", e3);
	puts("鏈棧元素:");
	PrintfLinkStack(&stack);
	printf("鏈棧元素個數:%d", GetLengthLinkStack(&stack));
	printf("\n");
	return 0;
}

執行結果截圖: