如何用C语言建立栈这种数据结构?

栈:是一种运算受限的线性表,仅在表尾进行插入和删除操作,这一端叫做栈顶,另一端叫做栈底。数据结构特点就是先进后出(LIFO)LIFO的是 “Last In First Out” 的英文缩写。
  1. 入栈(Push)从栈顶添加元素
  2. 出栈(Pop)从栈顶移除元素
  3. 获取栈顶元素(peek):获取栈顶的元素,但不删除它。
  4. 判断栈是否为空(isEmpty):检查栈是否为空。
  5. 获取栈的大小(size):返回栈中元素的数量。
  6. 时间复杂度o(1)即它们都只需要一次操作就可以完成。这是因为栈是一种线性的数据结构,其元素的添加和移除都发生在同一个位置,即栈顶。
 顺序栈:
#include 
#include 
#include 
#define MaxSize 10
typedef struct{
    int data[MaxSize];
    int top;
} SqStack;
//初始化栈
void InitStack(SqStack *s)
{
    s->top = -1;
}
//判断栈是否为空
bool StackEmpty(SqStack *S)
{
    if(S->top == -1)//空
    {
        return true;
    }else{
        return false;
    }
}
//入栈
bool Push(SqStack *S,int x)
{
    if(S->top == MaxSize - 1)//栈满了
    {
        return false;
    }
    //S->data[++S->top] = x
    S->top = S->top + 1;
    S->data[S->top] = x;
    return true;
}
//出栈
bool Pop(SqStack *S,int *x)
{
   if(S->top == -1)//空栈就别出栈了
   {
       return false;
   }
    //*x = S->data[S->top--]; // 这玩意儿是先取值在减top 所以--在后面 这要注意
    *x = S->data[S->top];
    S->top = S->top - 1;
    return true;
}
//获取栈顶元素
bool GetTop(SqStack *S,int *x)
{
    if(S->top == -1)
    {
        return false;
    }
    *x = S->data[S->top];
    return true;
}
//打印这个栈
void printStack(SqStack S)
{
    printf("[");
    while (!StackEmpty(&S)) {
        int x = -1;
        Pop(&S, &x);
        printf(" %d ",x);
    }
    printf("]\n");
}
int main(int argc, const char * argv[]) {
    SqStack S;
    InitStack(&S);
    Push(&S, 1);
    Push(&S, 2);
    Push(&S, 3);
    Push(&S, 4);
    Push(&S, 5);
    Push(&S, 6);
    int x = -1;
    printStack(S);
    Pop(&S, &x);
    printStack(S);
    return 0;
}
链栈:
#include 
#include 
#include 
typedef struct LNode
{
    int data;
    struct LNode *next;
}*LiStack;
bool InitLiStack(LiStack* S)
{
    *S = (LiStack)malloc(sizeof(LiStack));
    if(*S == NULL){
        return false;
    }
    (*S)->next = NULL;
    return true;
}
bool Push(LiStack *S,int x)
{
    struct LNode* new_node = (struct LNode*)malloc(sizeof(struct LNode));
    new_node->data = x;
    new_node->next = *S;
    *S = new_node;
    return true;
}
bool Pop(LiStack *S,struct LNode *x)
{
    *x = **S;
    (*S) = (*S)->next;
    return true;
}
void printLiStack(LiStack S)
{
    printf("[");
    while (S != NULL) {
        printf(" %d ",S->data);
        S = S->next;
    }
    printf("]\n");
}
int GetTop(LiStack S)
{
    if(S == NULL){
        return -1;
    }
    return S->data;
}
int main(int argc, const char * argv[]) {
    LiStack LS;
    InitLiStack(&LS);
    Push(&LS, 1);
    Push(&LS, 2);
    Push(&LS, 3);
    Push(&LS, 4);
    Push(&LS, 5);
    Push(&LS, 6);
    Push(&LS, 7);
    Push(&LS, 8);
    
    printLiStack(LS);
    
    struct LNode x;
    Pop(&LS, &x);
    Pop(&LS, &x);
    printf("x = %d\n",x.data);
    printLiStack(LS);
    printf("top = %d\n",GetTop(LS));
    return 0;
}
 链栈和顺序栈都是数据结构中的栈,它们的主要区别在于它们的实现方式和存储方式。
顺序栈是使用数组来实现的,它的优点是操作比较方便,缺点是需要分配连续的内存空间,可能会造成内存浪费。
链栈是使用链表来实现的,它的优点是可以动态地分配内存,不会造成内存浪费,缺点是操作相对于顺序栈来说稍微复杂一些。

相较于顺序栈,链栈一般不会出现栈满的情况。

栈是种比较简单的数据结构,在实际的生活中应用广泛。
  1. 栈式搜索:在解决迷宫问题、图的深度优先搜索等算法中,可以使用栈来记录搜索路径,从而找到从起点到终点的所有可能路径。

  2. 括号匹配:判断一段表达式是否合法,就需要使用栈。
  3. 浏览器的前进和后退:浏览器在处理浏览历史记录时,也是使用了一个栈结构,先进后出。
  4. 表达式计算:利用栈可以很容易地实现表达式的计算和括号匹配。
  5. 火车车厢重排:栈在火车车厢重排问题中也有应用,通过将车厢的排列顺序存储在一个栈中,可以方便地实现车厢的重新排列。
  6. 操作系统中的进程调度:在操作系统中,可以利用栈来保存待执行的进程信息,从而实现进程的调度。
  7. 路由器中的路由表:在路由器中,可以使用栈来存储路由表信息,从而确定数据包的最佳传输路径。
  8. Web服务器的HTTP请求处理:在Web服务器中,可以使用栈来处理HTTP请求,例如处理请求头和请求体。
  9. 其他方面各个的应用

你可能感兴趣的:(数据结构)