1. 程式人生 > 實用技巧 >如何輕鬆使用 C 語言實現一個棧?​

如何輕鬆使用 C 語言實現一個棧?​

什麼是資料結構?

資料結構是什麼?要了解資料結構,我們要先明白資料和結構,資料就是一些int char 這樣的變數,這些就是資料,如果你是一個籃球愛好者,那麼你的球鞋就是你的資料,結構就是怎麼把這些資料排列組合,怎麼把資料擺放好才能方便你找到這些資料,把資料和結構合在一起理解就是所謂的資料結構,簡單點,就是處理資料的方式方法。

平時在家裡面,你有沒有隨便擺放自己的鞋子,然後要找鞋子的時候要花費非常多是時間,可能你老婆也很生氣,每天都亂擺鞋子導致她打掃衛生非常麻煩,然後有一天,你買了一個非常酷的鞋架,有了這個鞋架之後,你的鞋子終於有家了,這個鞋架就是起到處理鞋子的作用了。


什麼是棧?

棧可以理解為資料結構中的一種,這種資料結構的特點是先進去的人「資料」後出來,就像下面的圖片一樣,如果棧是一個洞,人「資料」只能從洞的一個口進去,然後出來也只能從一個口出來,而且洞的寬度就只能容納一個人「資料」,好了,那先進去的那個人「資料」最傻逼了,一定要等後面進來的人「資料」都先出去了才能出去。



用 C 語言實現一個棧

 我寫程式碼是很水的,之前有一個同學寫了一個棧讓我檢查,我看了下,好像我寫程式碼的能力比他厲害一些,程式碼比較簡單,然後講一下幾個比較重要的函式,希望大家在面試的時候,隨手就甩出一個棧“砸死”面試官,哈哈。
#include "stdio.h"

#include "stdlib.h"

struct List{

    int data;

    struct List * next;

};

struct Stack{

    struct List *head;

    int size;

};

struct Stack * StackInit(void
) { struct Stack *stack = NULL; stack = (struct Stack*)malloc(sizeof(struct Stack)); stack->head = (struct List *)malloc(sizeof(struct List)); stack->head->next = NULL; stack->size = 0; return stack; } int StackPush(struct Stack *stack,int data) { struct
List *tmp = (struct List *)malloc(sizeof(struct List)); tmp->data = data; tmp->next = stack->head->next; stack->head->next = tmp; stack->size++; //printf("push:%d \n",data); return 0; } int IsStackEmpty(struct Stack *stack) { /*如果頭指標指向下一個為空,說明棧為空*/ if(stack->head->next == NULL) return 1; else return 0; } int StackPop(struct Stack *stack,int *data) { struct List *tmp = NULL; if(IsStackEmpty(stack)) return -1; tmp = stack->head->next; *data = tmp->data; stack->head->next = tmp->next; stack->size--; free(tmp); //printf("pop:%d \n",*data); return 0; } int main(void) { int i = 0; struct Stack *stack = NULL; stack = StackInit(); for(i = 0;i<5;i++) { StackPush(stack,i); } for(i = 0;i<5;i++) { int data = 0; StackPop(stack,&data); printf("%d ",data); } printf("\n"); return 0; }

1- 棧頭部

棧頭部,也就是棧頂指標,我們用指標單鏈表實現一個棧,一定要知道這個棧頂的指標,有頭就有棧,沒有頭,這個棧也就跨了。

struct Stack *stack = NULL;

    stack = StackInit();

這個就是定義一個棧,也就是malloc出來一個記憶體,專門存這個棧頂的。


2- 出棧

出棧的方法跟我之前說的差不多,只不過出棧程式碼上需要做判斷。

int StackPop(struct Stack *stack,int *data)

{

    struct List *tmp = NULL;

    if(IsStackEmpty(stack))

        return -1;

    tmp = stack->head->next;

    *data = tmp->data;

    stack->head->next = tmp->next;

    stack->size--;

    free(tmp);

    //printf("pop:%d \n",*data);

    return 0;

}

先判斷這個棧是不是空的,是不是空的判斷方法就是通過判斷head->next的指標是否為空。

然後把head->next 這個位置的資料取出來,取出來後,再把head->next的指標指向 取出來這個位置 的next 位置。

然後再記得free掉。就Ok了。


3- 入棧

入棧的操作和出棧的操作剛好相反,就是改變一下位置和指標的指向。

int StackPush(struct Stack *stack,int data)

{

    struct List *tmp = (struct List *)malloc(sizeof(struct List));

    tmp->data = data;

    tmp->next = stack->head->next;

    stack->head->next = tmp;

    stack->size++;

    //printf("push:%d \n",data);

    return 0;

}

用陣列來實現一個棧

陣列本身是一種資料結構,使用陣列實現一個棧也是非常簡單方便的,大家請看。

#include "stdio.h"

#include "stdlib.h"

/*棧的大小*/

#define LENGHT (100)

struct Stack{

    int stack_array[LENGHT];

    unsigned int size;//棧動態長度

};

struct Stack * StackInit(void)

{

    struct Stack *stack = NULL;

    stack =  (struct Stack*)malloc(sizeof(struct Stack));

    stack->size = 0;

    return stack;

}

int StackPush(struct Stack *stack,int data)

{

    if(stack->size >= LENGHT)

    {

        printf("stack is full\n");

        return (-1);

    }

    stack->stack_array[stack->size] = data;

    stack->size++;

    //printf("push:%d size:%d\n",data,stack->size);

    return 0;

}

int IsStackEmpty(struct Stack *stack)

{

    /*如果頭指標指向下一個為空,說明棧為空*/

    if(stack->size == 0)

        return 1;

    else

        return 0;

}

int StackPop(struct Stack *stack,int *data)

{

    stack->size--;

    if(IsStackEmpty(stack))

        return -1;

    *data = stack->stack_array[stack->size];

    //printf("pop:%d size:%d\n",*data,stack->size);

    return 0;

}

int main(void)

{

    int i = 0;

    struct Stack *stack = NULL;

    stack = StackInit();

    for(i = 0;i<20;i++)

    {

        StackPush(stack,i);

    }

    for(i = 0;i<21;i++)

    {

        int data = 0;

        StackPop(stack,&data);

        printf("%d \n",data);

    }

    printf("\n");

    return 0;

}

總結

既然有棧,就會有和棧不一樣的資料結構,有一種資料結構叫做佇列,棧的資料結構特點是先進後出,佇列的資料結構特點是先進先出,有點意思,棧和佇列做驅動的同學很少需要自己寫程式碼實現,正常情況下都是SDK集成了方法,直接呼叫介面就好了,但是寫應用的同學,經常要自己實現一個棧或者佇列,特別是大企業面試,這些算是非常基礎的題目,最好是閉著眼睛就能寫出來的那種。


如果你想快速掌握C/C++程式設計,小編推薦我的C語言/C++程式設計學習基地【點選進入】!


都是學程式設計小夥伴們,帶你入個門還是簡簡單單啦,一起學習,一起加油~

涉及:程式設計入門、遊戲程式設計、windows程式設計、Linux程式設計、Qt、黑客等等......