線性結構常見應用之一——棧

定義:

棧是一種“先進後出”(後進先出)的存儲結構,類似於一個裝東西的箱子,即先裝進去的後出來


實際上說,棧是操作受限的鏈表


分類:

靜態棧

動態棧

以數組爲基本內核的稱爲靜態


下面舉個例子

1

# include <stdio.h>
# include <malloc.h>
 
void f(int k)
{
	int m;

	double * q = (double *)malloc(200);
}

int main(void)
{
	int i = 10;
	int * p = (int *)malloc(100);

	return 0;
}

    這個程序沒什麼實際意義,舉這麼一個程序,僅僅是想說明一下,內存的分配問題

    在這個程序中,kmqip還有那爲q動態分配的200個字節的內存和爲p動態分配的100個字節的內存,計算機爲它們都分配了內存,所不同的是,爲kmqip這些靜態變量分配的內存是在棧中分配的,而爲那動態分配的200個和100個字節的內存是在堆中分配的

總結起來:

局部變量所佔內存是在棧裏邊分配的

動態分配的內存是在堆裏邊分配的

棧和堆表示內存分配的一種方式


還有就是

靜態的或者說局部變量以壓棧(入棧)和出棧的方式分配內存

動態分配是以堆排序的方式分配內存

算法:

出棧

壓棧(入棧)


應用:

函數調用

中斷

表達式求值

內存分配

緩衝處理

迷宮


再舉一個例子

2

# 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;  //PSTACK 等價於 struct STACK *

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

int main(void)
{
	STACK S;  //STACK 等價於 struct Stack
	int val;

	init(&S);  //目的是造出一個空棧
	push(&S, 1); //壓棧
	push(&S, 2);
	push(&S, 3);
	push(&S, 4);
	push(&S, 5);
	push(&S, 6);
	traverse(&S); //遍歷輸出
	
//	clear(&S);
//	traverse(&S); //遍歷輸出

	if ( pop(&S, &val) )
	{
		printf("出棧成功,出棧的元素是%d\n", val);
	}
	else
	{
		printf("出棧失敗!\n");
	}

	traverse(&S); //遍歷輸出

	return 0;
}

void init(PSTACK pS)
{
	pS->pTop = (PNODE)malloc(sizeof(NODE));
	if (NULL == pS->pTop)
	{
		printf("動態內存分配失敗!\n");
		exit(-1);
	}
	else
	{
		pS->pBottom = pS->pTop;
		pS->pTop->pNext = NULL; //pS->Bottom->pNext = NULL;
	}
}

void push(PSTACK pS, int val)
{
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	
	pNew->data = val;
	pNew->pNext = pS->pTop; //pS->Top不能改成pS->Bottom
	pS->pTop = pNew;

	return;
}

void traverse(PSTACK pS)
{
	PNODE p = pS->pTop;

	while (p != pS->pBottom)
	{
		printf("%d  ", p->data);
		p = p->pNext;
	}
	printf("\n");

	return;
}

bool empty(PSTACK pS)
{
	if (pS->pTop == pS->pBottom)
		return true;
	else
		return false;
}

//把pS所指向的棧出棧一次,並把出棧的元素存入pVal形參所指向的變量中,如果出棧失敗,返回false,否則返回true
bool pop(PSTACK pS, int * pVal)
{
	if ( empty(pS) ) //pS本身存放的就是S的地址
	{
		return false;
	}
	else
	{
		PNODE r = pS->pTop;
		*pVal = r->data;
		pS->pTop = r->pNext;
		free(r);
		r = NULL;

		return true;
	}
}

//clear清空
void clear(PSTACK pS)
{
	if (empty(pS))
	{
		return;
	}
	else
	{
		PNODE p = pS->pTop;
		PNODE q = NULL;

		while (p != pS->pBottom)
		{
			q = p->pNext;
			free(p);
			p = q;
		}
		pS->pTop = pS->pBottom;
	}
}

輸出結果爲:


在本程序的第11到第15行是定義了一個棧,其中有兩個指針變量,一個指向棧的頂部,一個指向棧的底部。

1721行的函數分別表示初始化棧、壓棧、遍歷、判斷棧是否成功輸出、清空棧

94100行的函數是判斷棧是否爲空 


另外,如果把第37行代碼前的 // 去掉,則棧爲空,此時再次輸出(遍歷)棧,即把第38行代碼前的 // 去掉,則輸出結果爲

出棧失敗,是因爲棧已經爲空,無法輸出,所以輸出失敗


【所有代碼均在windows系統下C-Free5.0下運行通過】

(如有錯誤,敬請指正)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章