歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

動態順序棧的C語言實現

大家寫的順序棧一般都是用數組實現,大小固定,一旦壓棧數量超過棧大小則會發生越界!現在寫一個用malloc和realloc實現的動態順序棧,當壓棧數量超過棧大小時,程序可根據所需求空間自動調節棧大小,以滿足要求!代碼如下,調試通過,放心使用!

此動態順序棧的棧底空間設為空,不用來作為存放數據的有效空間,故當輸入棧大小為N時棧實際可用空間為(N-1)即只能壓棧(N-1)次,否則若將使用空間也定為N的話,將發生類似“DAMAGE:after Normal block(#51) at 0x..........”的錯誤提示,即“越界”錯誤,詳見文章末!

/************************************************
 運行平台:vc++6.0
 實現功能:利用realloc實現動態順序棧(棧空間可增大)
************************************************/
 #include<stdio.h>
 #include<stdlib.h>
 #include<malloc.h>
 
typedef int eletype; /* 重新定義元素類型 */
 
#define INIT_SIZE 5  /* 棧初始大小 */
 
/* 定義一個可以操作動態順序棧的結構體 */
 typedef struct stack
{
    eletype *p_top;    /* 棧頂指針 */
    eletype *p_bottom; /* 棧底指針 */
    int stack_size;    /* 棧大小 */
 }malloc_seqstack;      /* 動態順序棧malloc_sequence_stack */
 
/*****************棧基本操作函數聲明********************/
 void seqstack_init(malloc_seqstack *p_stack, int init_size);
 bool seqstack_full(malloc_seqstack *p_stack);
 bool seqstack_empty(malloc_seqstack *p_stack);
 void seqstack_push(malloc_seqstack *p_stack, int length, eletype value);
 eletype seqstack_pop(malloc_seqstack *p_stack);
 void seqstack_destroy(malloc_seqstack *p_stack);
 /*******************************************************/
 

/********************************************************
 *函數名稱:main
 *函數功能:程序入口
 *入口參數:空
 *返 回 值:0
 ********************************************************/
 int main(void)
 {   
    int i = 0;
    int num = 0;
    int value = 0;
   
    /*******在棧中為結構體分配空間*******
    malloc_seqstack stack;
    malloc_seqstack *p_stack = &stack;
    ************************************/
 
    /*******在堆中為結構體分配空間*******/
    malloc_seqstack *p_stack = (malloc_seqstack *)malloc(sizeof(malloc_seqstack));
   

    seqstack_init(p_stack, INIT_SIZE);
   
    printf("請輸入需要的動態順序棧大小:\n");
    scanf("%d", &num);
 
    printf("請輸入%d個數值:\n", num-1);   
    for(i=0; i<num-1; i++) 
    {
        scanf("%d", &value);     
        seqstack_push(p_stack, num, value);
    }
   
    printf("依次出棧:\n");
    for(i=0; i<num-1; i++)       
    {
        printf("%3d", seqstack_pop(p_stack));
    }
    printf("\n\n");
   
    seqstack_destroy(p_stack);
   
    return 0;
 }
 
/********************************************************
 *函數名稱:seqstack_init
 *函數功能:初始化動態順序棧
 *入口參數:p_stack為指向結構體指針
            init_size為棧初始大小
 *返 回 值:空
 ********************************************************/
 void seqstack_init(malloc_seqstack *p_stack, int init_size)
 {
    p_stack->p_bottom = (eletype *)malloc(init_size * sizeof(eletype));
   
    if (p_stack->p_bottom == NULL)
    {
        exit(-1);
    }
    p_stack->p_top = p_stack->p_bottom;
    p_stack->stack_size = init_size;
   
    return;
 }
 
/********************************************************
 *函數名稱:seqstack_full
 *函數功能:判斷棧是否為滿
 *入口參數:p_stack為指向結構體指針
 *返 回 值:1為滿,0為非滿
 ********************************************************/
 bool seqstack_full(malloc_seqstack *p_stack)
 { 
    return p_stack->p_top - p_stack->p_bottom >= p_stack->stack_size-1;
 }
 
/********************************************************
 *函數名稱:seqstack_empty
 *函數功能:判斷棧是否為空
 *入口參數:p_stack為指向結構體指針
 *返 回 值:1為空,0為非空
 ********************************************************/
 bool seqstack_empty(malloc_seqstack *p_stack)
 {
    return p_stack->p_top <= p_stack->p_bottom;
 }
 
/********************************************************
 *函數名稱:seqstack_push
 *函數功能:壓棧
 *入口參數:p_stack為指向結構體指針
            length為欲壓棧的數據個數
            value為欲壓棧的數值
 *返 回 值:空
 ********************************************************/
 void seqstack_push(malloc_seqstack *p_stack, int length, eletype value)
 {
    eletype *p_tmp = p_stack->p_bottom;
   
    if (seqstack_full(p_stack))
    {
        printf("棧已滿,系統將為其增加空間!\n");
       
        p_stack->p_bottom =
        (eletype *)realloc(p_stack->p_bottom, length*sizeof(eletype));
       
        if (!p_stack->p_bottom)
        {
            free(p_tmp);
            exit(-1);
        }
        p_stack->stack_size = length;
    }
    (p_stack->p_top)++;
    *(p_stack->p_top) = value;
   
    return;
 }
 
/********************************************************
 *函數名稱:seqstack_pop
 *函數功能:出棧
 *入口參數:p_stack為指向結構體指針
 *返 回 值:value為出棧數據
 ********************************************************/
 eletype seqstack_pop(malloc_seqstack *p_stack)
 {
    eletype value = 0;
   
    if (seqstack_empty(p_stack))
    {
        printf("棧已空!\n");
        exit(-1); 
    }
    value = *(p_stack->p_top--);
   
    return value;
 }
 
/********************************************************
 *函數名稱:seqstack_destroy
 *函數功能:銷毀棧
 *入口參數:p_stack為指向結構體指針
 *返 回 值:空
 ********************************************************/
 void seqstack_destroy(malloc_seqstack *p_stack)
 {
    free(p_stack->p_bottom);
    free(p_stack);
    p_stack->stack_size = 0;
    p_stack->p_bottom = NULL;
    p_stack->p_top = NULL;
    p_stack = NULL; 
   
    return;
 }
 
/***********************程序結束************************/

程序運行結果:

棧越界時提示的錯誤信息:

C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm

讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm

讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm

將C語言梳理一下,分布在以下10個章節中:

  1. Linux-C成長之路(一):Linux下C編程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成長之路(二):基本數據類型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成長之路(三):基本IO函數操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成長之路(四):運算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成長之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成長之路(六):函數要義 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成長之路(七):數組與指針 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成長之路(八):存儲類,動態內存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成長之路(九):復合數據類型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成長之路(十):其他高級議題

Copyright © Linux教程網 All Rights Reserved