1. 程式人生 > >資料結構--c實現棧的出棧入棧

資料結構--c實現棧的出棧入棧

 一,只有棧頂的情況。

1,首先定義連結串列單節點:

typedef struct node
{
    ElementType data;
    struct node *next
}StackNode ,*LinkStack;


2. 然後初始化,也就是給棧頂節點的元素賦值NULL 。

void InitStack(LinkStack top)
{
    top->next = NULL;
}

這時候棧頂的連結串列節點如下:

3. 入棧

BOOL Push(LinkStack top,ElementType element)
{
    StackNode *temp;
    temp=(StackNode*)malloc(sizeof(StackNode));

    if (temp==NULL)
    {
        return FALSE;
    }
    temp->data=element;
    temp->next=top->next;
    top->next=temp;

    return TRUE;
}

 

  1. 執行完一次入棧:
  • 先malloc temp1單節點,

temp=(StackNode*)malloc(sizeof(StackNode));

  • 然後把num放入temp1的data。

temp->data=element;

  • 然後讓temp節點的next 指向top原來指向的位置。

temp->next=top->next;

  • 然後更換頭結點的next 指向為temp1的位置

top->next=temp;

在棧區資料儲存形式如下:

可以看到,top的next 指向了 temp1,然後,temp1的next 指向了NULL。NULL相當於棧底部。

  1. 如果再執行一次入棧,
  • 又會malloc temp2 單節點。這時候,num2存入新malloc 的temp2的data元素中。

 

  • 然後把top原來的指向位置也就是temp1的位置,賦值給temp2的指向,這時就變成了temp2的next 指向temp1。

  • 然後將top的指向更換到temp2的位置,這時候,top的下面不再是temp1,而是插入了temp2.

整理下上面的圖,把temp2 插到top跟temp1之間,就是如下形式:

再往後,繼續push入棧,temp3就插入到temp2根棧頂top 之間,temp(n) 插入到temp(n-1)跟top之間。。。

4,出棧

接著看上面的temp2 開始看。

//出棧
BOOL Pop(LinkStack top,ElementType *element)
{
    if (IsEmpty(top))
    {
        return FALSE;
    }

    StackNode *temp=top->next;
    *element = temp->data;
    top->next = temp->next;
    free(temp);
    temp=NULL;
    return TRUE;
}

先要判斷下top是否為空,為空,就找不到temp2了。

if (IsEmpty(top))
    {
        return FALSE;
    }
然後根據top的next 找到temp2,取出temp2內的data 元素,

  StackNode *temp=top->next;
    *element = temp->data;

 

然後把temp2的next 指向(temp1的位置)賦值給top的next 指向,為後面刪除temp2 做準備,這樣就不會把temp1給弄丟了。

top->next = temp->next;

接著就可以放心刪除temp2 了

free(temp);
    temp=NULL;

這是,棧區的儲存形式就又回到了入棧temp1的狀態:

出棧比較簡單,分析完畢。

下面是完整程式。

#include <stdio.h>
#include <stdlib.h>
typedef int BOOL;
typedef int ElementType;
#define TRUE 1
#define FALSE 0

#define STACK_SIZE 100

typedef struct node
{
    ElementType data;
    struct node *next
}StackNode ,*LinkStack;

//初始化

void InitStack(LinkStack top)
{
    top->next = NULL;
}

//是否為空

BOOL IsEmpty(LinkStack top)
{
    if (top->next ==NULL)
    {
        return TRUE;
    }else
    {
        return FALSE;
    }
}

//入棧

BOOL Push(LinkStack top,ElementType element)
{
    StackNode *temp;
    temp=(StackNode*)malloc(sizeof(StackNode));

    if (temp==NULL)
    {
        return FALSE;
    }
    temp->data=element;
    temp->next=top->next;
    top->next=temp;

    return TRUE;
}

//出棧
BOOL Pop(LinkStack top,ElementType *element)
{
    if (IsEmpty(top))
    {
        return FALSE;
    }

    StackNode *temp=top->next;
    *element = temp->data;
    top->next = temp->next;
    free(temp);
    temp=NULL;
    return TRUE;
}

void InvertedSequence(int num)
{
    int i=0;
    int result =0;
    LinkStack top;
    top =(LinkStack)malloc(sizeof(StackNode));
    InitStack(top);
    printf("資料輸入為:\n");
    for(int i=0;i<num;i++)
    {
        //入棧
        Push(top, i);
        printf("%d",i);
    }

    printf("\n資料輸出為:\n");

    while(!IsEmpty(top))
    {
        //出棧
        Pop(top,&result);
        printf("%d",result);
    }
    printf("\n");
}

int main()
{
    //printf("Hello world!\n");
    int num=20;
    InvertedSequence(num);
    return 0;
}

二,同時又棧頂跟棧底的情況

具體就不詳細分析了,跟上面差不多。

差別在於,將棧頂,棧底,重新用一個結構體包起來,並初始化時,將棧底跟棧頂指向同一塊記憶體區域。

 

typedef struct node
{
    ElementType data;
    struct node *next;

}Node,*pNode;

typedef struct stack
{
    pNode top;
    pNode bottom;
}Stack,*pStack;

BOOL InitStack(pStack ps)
{
    if (ps==NULL)
    {
        return FALSE;
    }
    ps->top=(pNode)malloc(sizeof(Node));
    if (ps->top==NULL)
    {
        return FALSE;
    }
    ps->bottom=ps->top; //棧頂,跟棧底都指向同一記憶體塊。
    ps->top->next=NULL;

    return TRUE;
}

其實這裡棧底基本沒什麼用

詳細code 如下:

#include <stdio.h>
#include <stdlib.h>
typedef int BOOL;
typedef int ElementType;
#define STACK_SIZE 100
#define TRUE 1
#define FALSE 0

typedef struct node
{
    ElementType data;
    struct node *next;

}Node,*pNode;

typedef struct stack
{
    pNode top;
    pNode bottom;
}Stack,*pStack;

BOOL InitStack(pStack ps)
{
    if (ps==NULL)
    {
        return FALSE;
    }
    ps->top=(pNode)malloc(sizeof(Node));
    if (ps->top==NULL)
    {
        return FALSE;
    }
    ps->bottom=ps->top; //棧頂,跟棧底都指向同一記憶體塊。
    ps->top->next=NULL;

    return TRUE;
}

 BOOL Push(pStack ps,ElementType num)
 {
     Node *temp=(Node*) malloc(sizeof(Node));//定義新節點,分配記憶體空間
     if (temp==NULL)
     {
         return FALSE;
     }
     temp->data=num;
     temp->next=ps->top;//讓新節點指向棧頂
     ps->top=temp;//讓新節點成為棧頂,並新棧頂指向的是舊棧頂
     return TRUE;
 }

 BOOL Pop(pStack ps,ElementType *num)
 {
     if(ps->top->next==NULL)
     {
        return FALSE;
     }
    pNode  temp = ps->top;//先取出top 節點

    *num = temp->data;//從top節點中取出元素data

    ps->top = temp->next;//top節點修改,更改棧頂為top的下一個節點

    free(temp);
    temp=NULL;
    return TRUE;
}
void InvertedSequence(int num)
{
    int result =0;

    pStack ps =(pStack)malloc(sizeof(Stack));

    InitStack(ps);
    printf("入棧開始\n");
    for (int i=0;i<num;i++)
    {
        Push(ps,i);
        printf("%d\t",i);
    }
    printf("\n出棧開始:\n");

    while((ps->top)!=ps->bottom)
    {
        Pop(ps,&result);
        printf("%d\t",result);
    }

}
int main()
{
    int num =10;
    InvertedSequence(num);
    return 0;
}