数据结构,栈和列队

栈:一种特殊的线性表,只能从固定的一端入数据和出数据。一般把出入数据的一端叫栈顶,另一端叫栈底。

压栈:把数据放入栈中,叫压栈/入栈/进栈。 压栈在栈顶。

出栈:把数据移除栈中,叫出栈。出栈也在栈顶。

栈的出入顺序遵从——后入先出的原则。LIFO(last in first out)。

 

58fc2b5f798c483d8eb61af1751d64eb.png

 

上图压栈按照1234的顺序连续放,出的时候是4321。

 

栈的实现:

栈一般用链表和顺序表实现。不过一般用顺序表。因为插入删除都是从尾部操作,如果用链表,删尾要遍历,有点麻烦。顺序表就很方便插入删除了。

写一个栈主要实现栈的以下功能:

1.初始化和销毁栈

2.往栈中插入数据

3.从栈顶取出并删除数据

4.栈是否为空的判断

5.栈顶的数据是什么

6.栈中有效个数有多少

下面是stack.c文件,具体实现栈的各个功能。其他测试代码和头文件就不放了。

 
  1. void StackInit(Stack* ps)

  2. {

  3. ps->_a = NULL;

  4. ps->_capacity = ps->_top = 0;

  5. }

  6.  
  7. void StackPush(Stack* ps, STDataType data)

  8. {

  9. assert(ps);

  10. if (ps->_capacity == ps->_top)

  11. {

  12. int newcapacity = ps->_capacity == 0 ? 4 : ps->_capacity * 2;

  13. STDataType* ptr = (STDataType*)malloc(sizeof(STDataType) * newcapacity);

  14. if (ptr == NULL)

  15. {

  16. perror("StackPush:malloc failed");

  17. exit(1);

  18. }

  19. ps->_a = ptr;

  20. ps->_capacity = newcapacity;

  21. }

  22.  
  23. ps->_a[ps->_top] = data;

  24. ps->_top++;

  25. }

  26.  
  27. void StackPop(Stack* ps)

  28. {

  29. assert(ps);

  30. assert(!StackEmpty(ps));

  31. printf("%d\n", ps->_a[ps->_top - 1]);

  32. ps->_top--;

  33. }

  34.  
  35. bool StackEmpty(Stack* ps)

  36. {

  37. return ps->_top == NULL;

  38. }

  39.  
  40. // 获取栈顶元素

  41. STDataType StackTop(Stack* ps)

  42. {

  43. assert(ps);

  44. assert(!StackEmpty(ps));

  45. return ps->_a[ps->_top - 1];

  46. }

  47.  
  48.  
  49. // 获取栈中有效元素个数

  50. int StackSize(Stack* ps)

  51. {

  52. return ps->_top;

  53. }

  54.  
  55.  
  56. // 销毁栈

  57. void StackDestroy(Stack* ps)

  58. {

  59. assert(ps);

  60. free(ps->_a);

  61. ps->_a = NULL;

  62. ps->_capacity = ps->_top = 0;

  63. }

 

队列:一种特殊的线性表,只能从固定的一端入数据,从另一端出数据。遵循先入先出(FIFO)的原则。一般把出数据的一端叫队头,入数据的一端叫队尾。

队列要频繁的头删尾插,如果用顺序表,就要在删除时,不断地挪动后面的数。效率有点低。所以一般用链表实现。

理解原理以后,实现也很简单。

791c84ab19624111910f2cfb6938b797.png

 
  1.  
  2. void QueueInit(Queue* q)

  3. {

  4. assert(q);

  5. q->_front = q->_rear = NULL;

  6. }

  7.  
  8. void QueuePush(Queue* q, QDataType data)

  9. {

  10. assert(q);

  11. QNode* ptr = (QNode*)malloc(sizeof(QNode));

  12.  
  13.  
  14. ptr->_data = data;

  15. ptr->_next = NULL;

  16.  
  17. if (q->_front == NULL)

  18. {

  19. q->_front = ptr;

  20. q->_rear = q->_front;

  21. }

  22. else

  23. {

  24. q->_rear->_next = ptr;

  25. q->_rear = q->_rear->_next;

  26. }

  27. }

  28.  
  29. void QueuePop(Queue* q)

  30. {

  31. assert(q);

  32. assert(!QueueEmpty(q));

  33.  
  34. printf("%d ", q->_front->_data);

  35. QNode* p = q->_front;

  36. q->_front = q->_front->_next;

  37. free(p);

  38. }

  39.  
  40. // 检测队列是否为空,如果为空返回非零结果,如果非空返回0

  41. int QueueEmpty(Queue* q)

  42. {

  43. return q->_front == NULL ? 1 : 0;

  44. }

  45.  
  46. // 获取队列头部元素

  47. QDataType QueueFront(Queue* q)

  48. {

  49. assert(q);

  50. assert(!QueueEmpty(q));

  51.  
  52. return q->_front->_data;

  53. }

  54.  
  55. // 获取队列队尾元素

  56. QDataType QueueBack(Queue* q)

  57. {

  58. assert(q);

  59. assert(!QueueEmpty(q));

  60.  
  61. return q->_rear->_data;

  62. }

  63.  
  64. // 获取队列中有效元素个数

  65. int QueueSize(Queue* q)

  66. {

  67. assert(q);

  68. int count = 0;

  69. QNode* cur = q->_front;

  70. while (cur)

  71. {

  72. count++;

  73. cur = cur->_next;

  74. }

  75. return count;

  76. }

  77.  
  78. // 销毁队列

  79. void QueueDestroy(Queue* q)

  80. {

  81. assert(q);

  82. QNode* cur = q->_front;

  83. while (cur)

  84. {

  85. QNode* next = cur->_next;

  86. free(cur);

  87. cur = next;

  88. }

  89. q->_front = q->_rear = NULL;

  90. }

 

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值