栈-链表-带头结点

1. **栈的结构定义:**
   - `LNode` 结构体定义了链表节点,包含一个整数 `data` 存储数据,以及一个指向下一个节点的指针 `next`。
   - `LinkStack` 是指向链表栈的指针。

2. **初始化栈:**
   - `Stack_Init` 函数用于初始化栈,创建头结点,并将头结点的 `next` 指针置为 `NULL`,表示空栈。头结点的 `data` 存储栈的长度。

3. **判断栈是否为空:**
   - `Stack_Empty` 函数通过判断头结点的 `next` 是否为 `NULL` 来判断栈是否为空。

4. **获取栈有效数据节点个数:**
   - `Stack_Length` 函数返回栈的长度,即头结点的 `data` 值。

5. **创建栈:**
   - `Stack_Create` 函数通过输入数据创建栈,每输入一个数据,创建一个新节点并插入到链表的头部。

6. **新元素入栈:**
   - `Stack_Push` 函数将新元素入栈,创建一个新节点,并将其插入到链表的头部。

7. **出栈:**
   - `Stack_Pop` 函数将栈顶元素出栈,首先检查栈是否为空,然后删除栈顶节点,并释放相应的内存。

8. **返回栈顶元素:**
   - `Stack_Get_Top` 函数返回指向栈顶元素的指针。

9. **打印栈所有值:**
   - `Stack_Show` 函数遍历链表栈,打印所有节点的数据。

10. **主函数演示:**
   - 主函数演示了栈的初始化、创建、入栈、出栈、获取栈顶元素等操作,并输出相应的结果。

#include <stdio.h>
#include<stdlib.h>
typedef struct LNode {
  int data;
  struct LNode * next;
} LNode, *LinkStack;

// 初始化栈
bool Stack_Init (LinkStack &pStack) {
  pStack = (LNode *) malloc(sizeof(LNode));
  if (pStack == NULL) return false;
  pStack->next = NULL;
  // 头结点存储栈长度
  pStack->data = 0;
  return true;
}

// 判断栈是否为空
bool Stack_Empty (LinkStack pStack) {
  // 或 pStack->data == 0;
  return pStack->next == NULL;
}

// 获取栈有效数据节点个数
int Stack_Length (LinkStack pStack)
{
  return pStack->data;
}

// 创建栈
LinkStack Stack_Create(LinkStack &pStack) {
  LNode *pTemp; int x;
  scanf("%d", &x);
  while (x != 999) {
    pTemp = (LNode *)malloc(sizeof(LNode));
    pTemp->data = x;
    pTemp->next = pStack->next;
    pStack->next = pTemp;
    pStack->data += 1;
    scanf("%d", &x);
  }
  return pStack;
}

// 新元素入栈
bool Stack_Push(LinkStack &pStack, int e) {
  LNode *pTemp = (LNode *)malloc(sizeof(LNode));
  pTemp->data = e;
  pTemp->next = pStack->next;
  pStack->next = pTemp;
  pStack->data += 1;
  return true;
}

// 出栈
bool Stack_Pop (LinkStack &pStack, int &e) {
  if (pStack->next == NULL) return false;
  LNode *p = pStack->next; // 待删除结点
  pStack->next = p->next;
  e = p->data;
  free(p);
  pStack->data -= 1;
  return true;
}

// 返回第一个
LNode* Stack_Get_Top (LinkStack pStack) {
  return pStack->next;
}

// 打印栈所有值
void Stack_Show (LinkStack pStack) {
  LNode *node = pStack->next;
  printf("栈值:");
  while (node != NULL) {
    printf("%d、", node->data);
    node = node->next;
  }
  printf("\n");
}

int main () {
  int i = -1;
  LinkStack pStack;
  Stack_Init(pStack);
  printf("栈判空:%s\n", Stack_Empty(pStack) ? "空" : "非空");

  Stack_Create(pStack);
  Stack_Show(pStack);
  printf("栈长度:%d\n\n", Stack_Length(pStack));

  printf("入栈:0\n");
  Stack_Push(pStack, 0);
  Stack_Show(pStack);
  printf("栈长度:%d\n\n", Stack_Length(pStack));
  
  printf("入栈:99\n");
  Stack_Push(pStack, 99);
  Stack_Show(pStack);
  printf("栈长度:%d\n\n", Stack_Length(pStack));

  Stack_Pop(pStack, i);
  printf("出栈:%d\n", i);
  Stack_Show(pStack);
  printf("栈长度:%d\n\n", Stack_Length(pStack));
  
  Stack_Pop(pStack, i);
  printf("出栈:%d\n", i);
  Stack_Show(pStack);
  printf("栈长度:%d\n\n", Stack_Length(pStack));

  LNode *top = Stack_Get_Top(pStack);
  printf("获取栈顶元素:%d\n\n", top == NULL ? -1 : top->data);

  printf("栈判空:%s\n", Stack_Empty(pStack) ? "空" : "非空");
  return 0;
}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是带头结点的链表的Go语言实现: ```go package main import ( "fmt" ) type ListNode struct { Val int Next *ListNode } type MyStack struct { Top *ListNode } /** Initialize your data structure here. */ func Constructor() MyStack { return MyStack{&ListNode{0, nil}} } /** Push element x onto stack. */ func (this *MyStack) Push(x int) { newNode := &ListNode{x, this.Top.Next} this.Top.Next = newNode } /** Removes the element on top of the stack and returns that element. */ func (this *MyStack) Pop() int { if this.Empty() { return -1 } val := this.Top.Next.Val this.Top.Next = this.Top.Next.Next return val } /** Get the top element. */ func (this *MyStack) Top() int { if this.Empty() { return -1 } return this.Top.Next.Val } /** Returns whether the stack is empty. */ func (this *MyStack) Empty() bool { return this.Top.Next == nil } func main() { stack := Constructor() stack.Push(1) stack.Push(2) stack.Push(3) fmt.Println(stack.Top()) // 3 fmt.Println(stack.Pop()) // 3 fmt.Println(stack.Pop()) // 2 fmt.Println(stack.Pop()) // 1 fmt.Println(stack.Empty()) // true } ``` 在上面的代码中,我们使用了一个`ListNode`结构体来表示链表点,其中`Val`表示当前点的值,`Next`表示下一个点的指针。`MyStack`结构体表示,其中`Top`是一个指向头结点的指针。 在`Constructor`函数中,我们初始化头结点。在`Push`函数中,我们将新元素插入到头结点之后。在`Pop`函数中,我们先判断是否为空,如果不为空,就返回顶元素并将其从中删除。在`Top`函数中,我们先判断是否为空,如果不为空,就返回顶元素。在`Empty`函数中,我们判断是否为空。 最后,在`main`函数中,我们测试了上述的功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值