数据结构--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;
}

猜你喜欢

转载自blog.csdn.net/linzihahaha/article/details/85254112