博客園把我的圖吞了。。。 別看了,服氣
后面居然又出來了。。。 可以繼續看了,還是服氣
接着上一次的順序棧,今天我記一下鏈棧,因為我也是剛學不久,有些地方也稍稍理解不了,所以,一起共勉。我會用我自己結合教材上畫的圖,爭取跟代碼一起結合,用文字和圖最大化的解釋代碼,這樣的話大家就可以很容易的懂了。在看本文之前,建議初學者們先看看書上的鏈棧的解釋,這里我將不會再仔細的說明了。假如你先看書再來看文章,效果會很不錯。廢話不多說了,大神勿噴,有錯誤請在下方評論區指出,讓我和后來的初學者們一起進步。
# include<stdio.h>
# include<stdlib.h>//malloc free 的頭文件 或者用# include<malloc.h>
# define FALSE 0
# define TRUE 1
typedef struct node//定義節點
{
int data;
struct node * next;
} stacknode;
typedef struct//定義一個鏈棧
{
stacknode * top; //這是一個鏈棧的指針 就是一個箭頭 名為top 專門指向一個有着數據域和指針域的類型節點
int count;//計數器 記錄鏈棧的元素個數
} linkstack;
圖示如下:

void init(linkstack * s);//初始化
int em(linkstack * s);//判斷是否為空(鏈棧一般不會為滿)
int push(linkstack * s,int a);//入棧
int pop(linkstack * s,int * a);//出棧
int ding(linkstack * s,int * a);//只取棧頂元素(不對棧有任何操作)
int length(linkstack * s,int *a);//取鏈棧長度
void init(linkstack * s)
{
s->top=NULL;//該指針箭頭指向為空
s->count=0;//初始化時長度為零
}
圖示如下:

int em(linkstack * s)
{
return (s->top==NULL? TRUE:FALSE);
}
int push(linkstack * s,int a)
{
stacknode * p=(stacknode *)malloc(sizeof(stacknode));//申請生成新節點
if(p==NULL)//申請不成功
return FALSE;
else
{
p->data=a;//掛載
p->next=s->top;//新節點的指針域指向原棧頂節點
s->top=p;//棧頂指針指向新節點
s->count++;
return TRUE;
}
}
圖示如下:

大家思考一下,上面三行代碼的順序不可以亂,這是為什么呢?
int pop(linkstack * s,int *a)
{
stacknode * p;//定義臨時變量存儲節點 我也挺想不通為啥要弄個臨時節點
if(em(s))
return FALSE;
else
{
p=s->top;//把節點賦給臨時節點 //其實這時p與s->top已經融為一體了(為棧頂取了新名字)
* a =p->data;//將棧頂元素的值發送出去
s->top=p->next;
s->count--;
free(p);//所以free(p)就是free(s->top)
return TRUE;
}
}
圖示如下:

int ding(linkstack * s,int * a)
{
if(em(s))
return FALSE;
else
{
* a=s->top->data;
return TRUE;
}
}
int length(linkstack * s)
{
return s->count;
}
int main(void)
{
linkstack s;
int a,b,c,d;
init(&s);
push(&s,1);
push(&s,12);
push(&s,15);
push(&s,124);
push(&s,237);
ding(&s,&a);
c=length(&s);
printf("棧頂元素為:%d\n鏈棧長度為:%d\n",a,c);
while(!em(&s))
{
pop(&s,&d);
printf("%d ",d);
}
return 0;
}
代碼實現效果圖:

以上就是C語言實現鏈棧的方法了,雖然可能以后我們用別的語言時不用自己再編寫這些代碼,但是基本的原理我們還是要懂的。