堆栈:

  1. //
  2. // Created by mao on 16-9-16.
  3. //
  4.  
  5. #ifndef UNTITLED_STACK_H
  6. #define UNTITLED_STACK_H
  7. #define TRUE 1
  8. #define FALSE 0
  9.  
  10. typedef int STACK_TYPE;
  11. typedef struct stack{
  12. STACK_TYPE value;
  13. struct stack *next;
  14. } STACK;
  15.  
  16. void create_stack();
  17. void destory_stack();
  18. void push(STACK_TYPE value);
  19. STACK_TYPE pop();
  20. int isEmpty();
  21. #endif //UNTITLED_STACK_H

stack.h

  1. //
  2. // Created by mao on 16-9-16.
  3. //
  4. #include <stdlib.h>
  5. #include "stack.h"
  6.  
  7. static STACK *stack;
  8.  
  9. void create_stack()
  10. {
  11. stack = (STACK *)malloc(sizeof(STACK));
  12. stack -> next = NULL;
  13. }
  14.  
  15. void destory_stack()
  16. {
  17. STACK *pStack;
  18. while((pStack = stack -> next) != NULL){
  19. free(stack);
  20. stack = pStack;
  21. }
  22. }
  23.  
  24. void push(STACK_TYPE value)
  25. {
  26. STACK *new = (STACK *)malloc(sizeof(STACK));
  27. new -> next = stack;
  28. new -> value = value;
  29. stack = new;
  30. }
  31.  
  32. STACK_TYPE pop()
  33. {
  34. STACK_TYPE value = stack -> value;
  35. STACK *pStack = stack;
  36. stack = stack -> next;
  37. free(pStack);
  38. return value;
  39. }
  40.  
  41. int isEmpty()
  42. {
  43. return stack -> next == NULL ? TRUE : FALSE;
  44. }

stack.c

  1. #include <stdio.h>
  2. #include "stack.h"
  3.  
  4. int main()
  5. {
  6. //堆栈
  7. create_stack();
  8. push(10);
  9. push(20);
  10. push(30);
  11. pop();
  12. push(22);
  13. while(isEmpty() == FALSE){
  14. printf("%d \t", pop());
  15. }
  16. }

main.c

运行:

队列:

当使用数组作为队列时,如果只是一端插入一端弹出,那么当尾部没有空间时,便无法插入元素,一种解决方法是使用“环绕”数组,新元素可以存储到以前删除元素所留出来的空间中,这种方法称为循环数组。

循环数组有个问题,当队列为空,或者为满时,首位的下标是一样的,无法判断出此时队列的状态,所以在队列的rear后加一个空余的不使用的位置,用来判断队列的状态是满队列,还是空队列。

当为满队列时:

  1. (rear + 2) % QUEUE_SIZE = front

当为空队列时:

  1. (rear + 1) % QUEUE_SIZE = front

队列实现:

  1. //
  2. // Created by mao on 16-9-16.
  3. //
  4.  
  5. #ifndef UNTITLED_QUEUE_H
  6. #define UNTITLED_QUEUE_H
  7. #define TRUE 1
  8. #define FALSE 0
  9. #define QUEUE_SIZE 100
  10. #define ARRAY_SIZE (QUEUE_SIZE + 1)
  11. typedef int QUEUE_TYPE;
  12.  
  13. static QUEUE_TYPE queue[ARRAY_SIZE];
  14. static int front = 1;
  15. static int rear = 0;
  16.  
  17. void Q_delete();
  18. QUEUE_TYPE Q_first();
  19. void Q_insert(QUEUE_TYPE value);
  20. int Q_isEmpty();
  21. int Q_isFull();
  22. #endif //UNTITLED_QUEUE_H

queue.h

  1. //
  2. // Created by mao on 16-9-16.
  3. //
  4.  
  5. #include "queue.h"
  6. #include <assert.h>
  7.  
  8. void Q_delete()
  9. {
  10. assert(Q_isEmpty() == FALSE);
  11. front = (front + 1) % QUEUE_SIZE;
  12. front = (front) % QUEUE_SIZE;
  13. }
  14.  
  15. QUEUE_TYPE Q_first()
  16. {
  17. assert(Q_isEmpty() == FALSE);
  18. return queue[front];
  19. }
  20.  
  21. //队列插入数据,rear++
  22. void Q_insert(QUEUE_TYPE value)
  23. {
  24. assert(Q_isFull() == FALSE);
  25. rear = (rear + 1) % QUEUE_SIZE;
  26. queue[(rear) % QUEUE_SIZE] = value;
  27. }
  28.  
  29. int Q_isEmpty()
  30. {
  31. return (rear + 1) % QUEUE_SIZE == front ? TRUE: FALSE;
  32. }
  33.  
  34. int Q_isFull()
  35. {
  36. return (rear + 2) % QUEUE_SIZE == front ? TRUE : FALSE;
  37. }

queue.c

  1. #include <stdio.h>
  2. #include "queue.h"
  3.  
  4. int main()
  5. {
  6.  
  7. //插入队列
  8. Q_insert(10);
  9. Q_insert(12);
  10. Q_delete();
  11. Q_insert(22);
  12. Q_insert(30);
  13. printf("%d\n", Q_first());
  14. Q_delete();
  15. printf("%d\n", Q_first());
  16. Q_delete();
  17. printf("%d\n", Q_first());
  18. Q_delete();
  19.  
  20. return 1;
  21. }

main.c

运行:

二叉树:

  1. #ifndef UNTITLED_BINARYTREE_H
  2. #define UNTITLED_BINARYTREE_H
  3.  
  4. #include <assert.h>
  5. #define TREE_TYPE int
  6. #define ARRAY_SIZE 100
  7. #define TREE_SIZE (ARRAY_SIZE + 1)
  8. TREE_TYPE TREE[TREE_SIZE] = {0};
  9.  
  10. static unsigned int leftChild(unsigned int current)
  11. {
  12. return current * 2;
  13. }
  14.  
  15. static unsigned int rightChild(unsigned int current)
  16. {
  17. return current * 2 + 1;
  18. }
  19.  
  20. void insert(TREE_TYPE value)
  21. {
  22. unsigned int current = 1;
  23. while(TREE[current] != 0){
  24. if(value < TREE[current]){
  25. current = leftChild(current);
  26. }else{
  27. assert(TREE[current] != value);
  28. current = rightChild(current);
  29. }
  30. assert(current < TREE_SIZE);
  31. }
  32. TREE[current] = value;
  33. }
  34.  
  35. TREE_TYPE *find(TREE_TYPE value)
  36. {
  37. unsigned int current = 1;
  38. while (current < TREE_SIZE && TREE[current] != value){
  39. if(value < TREE[current]){
  40. current = leftChild(current);
  41. }else if(value > TREE[current]){
  42. current = rightChild(current);
  43. }
  44. }
  45. if(current < TREE_SIZE){
  46. return TREE + current;
  47. }else{
  48. return 0;
  49. }
  50. }
  51.  
  52. //根据指针计算数组下标
  53. static unsigned long getIndex(TREE_TYPE *ptr){
  54. assert(ptr >= TREE || ptr <= TREE + TREE_SIZE);
  55. return ptr - TREE;
  56. }
  57.  
  58. //内置先遍历接口
  59. void pre_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
  60. {
  61. if(current < ARRAY_SIZE && TREE[current] != 0){
  62. callback(TREE[current]);
  63. pre_order_traverse(leftChild(current), callback);
  64. pre_order_traverse(rightChild(current), callback);
  65. }
  66. }
  67.  
  68. //先序遍历
  69. void do_pre_traverse(void(*callback)(TREE_TYPE value))
  70. {
  71. pre_order_traverse(1, callback);
  72. }
  73. //中序遍历
  74. void mid_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
  75. {
  76. if(current < ARRAY_SIZE && TREE[current] != 0){
  77. mid_order_traverse(leftChild(current), callback);
  78. callback(TREE[current]);
  79. mid_order_traverse(rightChild(current), callback);
  80. }
  81. }
  82.  
  83. void do_mid_order_traverse(void(*callback)(TREE_TYPE value))
  84. {
  85. mid_order_traverse(1, callback);
  86. }
  87.  
  88. //后续遍历
  89. void after_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
  90. {
  91. if(current < ARRAY_SIZE && TREE[current] != 0){
  92. after_order_traverse(leftChild(current), callback);
  93. after_order_traverse(rightChild(current), callback);
  94. callback(TREE[current]);
  95. }
  96. }
  97.  
  98. void do_after_order_traverse(void(*callback)(TREE_TYPE value))
  99. {
  100. after_order_traverse(1, callback);
  101. }
  102.  
  103. void print_tree(TREE_TYPE value)
  104. {
  105. printf("%d\t", value);
  106. }
  107.  
  108. #endif //UNTITLED_BINARYTREE_H

BinaryTree.h

  1. #include <stdio.h>
  2. #include "BinaryTree.h"
  3.  
  4. int main()
  5. {
  6. insert(20);
  7. insert(12);
  8. insert(5);
  9. insert(9);
  10. insert(16);
  11. insert(17);
  12. insert(25);
  13. insert(28);
  14. insert(26);
  15. insert(29);
  16.  
  17. do_pre_traverse(print_tree);
  18. printf("\n");
  19. do_mid_order_traverse(print_tree);
  20. printf("\n");
  21. do_after_order_traverse(print_tree);
  22. return 1;
  23. }

main.c

运行:

数组形式存放二叉树,会导致内存空间的浪费,尤其是非对称的二叉树,会造成大量的数组空间闲置。通过链式二叉树可以解决数组不充分的问题

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4.  
  5. typedef int TREE_TYPE;
  6. typedef struct TREE_NODE {
  7. TREE_TYPE value;
  8. struct TREE_NODE *leftPtr;
  9. struct TREE_NODE *rightPtr;
  10. } TREE_NODE;
  11. //指向树的根节点的指针
  12. TREE_NODE *root;
  13.  
  14. //创建根节点
  15. void createTree(TREE_TYPE value)
  16. {
  17. root = (TREE_NODE *) malloc(sizeof(TREE_NODE));
  18. root -> leftPtr = NULL;
  19. root -> rightPtr = NULL;
  20. root -> value = value;
  21. }
  22.  
  23. TREE_NODE * getRoot()
  24. {
  25. return root;
  26. }
  27.  
  28. //插入节点
  29. void insertNode(TREE_TYPE value)
  30. {
  31. TREE_NODE *current = root;
  32. //pos为待插入节点的父节点
  33. TREE_NODE *parent = root;
  34. while(current != NULL){
  35. //保存父节点信息
  36. parent = current;
  37. if(current -> value < value){
  38. current = current -> rightPtr;
  39. }else if(current -> value > value){
  40. current = current -> leftPtr;
  41. }else{
  42. //节点已存在
  43. return ;
  44. }
  45. }
  46. TREE_NODE *node = (TREE_NODE *) malloc(sizeof(TREE_NODE));
  47. assert(node != NULL);
  48. node -> leftPtr = NULL;
  49. node -> rightPtr = NULL;
  50. node -> value = value;
  51. //根据值得大小判断,node应该放在左节点还是右节点
  52. if(parent -> value > value){
  53. parent -> leftPtr = node;
  54. }else{
  55. parent -> rightPtr = node;
  56. }
  57. }
  58.  
  59. TREE_NODE * findNode(TREE_TYPE value)
  60. {
  61. TREE_NODE *current = root;
  62. while(current != NULL && current -> value != value){
  63. if( current -> value > value){
  64. current = current -> leftPtr;
  65. }else{
  66. current = current -> rightPtr;
  67. }
  68. }
  69. return current;
  70. }
  71.  
  72. void printNode(TREE_NODE * node)
  73. {
  74. printf("%d\t", node -> value);
  75. }
  76.  
  77. void pre_order_traverse(TREE_NODE * current)
  78. {
  79. if(current != NULL){
  80. printNode(current);
  81. pre_order_traverse(current -> leftPtr);
  82. pre_order_traverse(current -> rightPtr);
  83. }
  84. }
  85.  
  86. void mid_order_traverse(TREE_NODE * current)
  87. {
  88. if(current != NULL){
  89. mid_order_traverse(current -> leftPtr);
  90. printNode(current);
  91. mid_order_traverse(current -> rightPtr);
  92. }
  93. }
  94.  
  95. void after_order_traverse(TREE_NODE * current)
  96. {
  97. if(current != NULL){
  98. after_order_traverse(current -> leftPtr);
  99. after_order_traverse(current -> rightPtr);
  100. printNode(current);
  101. }
  102. }

BinaryTree.h

  1. #include <stdio.h>
  2. #include "BinaryTree.h"
  3.  
  4. int main()
  5. {
  6. createTree(20);
  7. insertNode(12);
  8. insertNode(5);
  9. insertNode(9);
  10. insertNode(16);
  11. insertNode(17);
  12. insertNode(25);
  13. insertNode(28);
  14. insertNode(26);
  15. insertNode(29);
  16.  
  17. pre_order_traverse(root);
  18. printf("\n");
  19. mid_order_traverse(root);
  20. printf("\n");
  21. after_order_traverse(root);
  22.  
  23. return 1;
  24. }

BinaryTree.c

运行:

C和指针 第十七章 经典数据类型 堆栈 队列 二叉树的更多相关文章

  1. C和指针 第十七章 习题

    17.8 为数组形式的树编写模块,用于从树中删除一个值,如果没有找到,程序节点 ArrayBinaryTree.c // // Created by mao on 16-9-18. // #inclu ...

  2. C和指针 第十七章 二叉树删除节点

    二叉树的节点删除分为三种情况: 1.删除的节点没有子节点,直接删除即可 2. 删除的节点有一个子节点,直接用子节点替换既可以 3.删除的节点有两个子节点. 对于第三种情况,一般是不删除这个节点,而是删 ...

  3. 第二十七章 system v消息队列(三)

    消息队列实现回射客户/服务器 msg_srv.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> ...

  4. 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索

    第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...

  5. Gradle 1.12 翻译——第十七章. 从 Gradle 中调用 Ant

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  6. Linux内核设计第十七章笔记

    第十七章 设备与模块 关于设备驱动和设备管理,四种内核成分 设备类型:在所有unix系统中为了统一普通设备的操作所采用的分类 模块:Linux内核中用于按需加载和卸载目标代码的机制 内核对象:内核数据 ...

  7. 【C++】《C++ Primer 》第十七章

    第十七章 标准库特殊设施 一.tuple类型 tuple是类似pair的模板,每个pair的成员类型都不相同,但每个pair都恰好有两个成员. 不同的tuple类型的成员类型也不相同,一个tuple可 ...

  8. 《Go语言圣经》阅读笔记:第三章基础数据类型

    第三章 基础数据类型 Go语言将数据类型分为四类: 基础类型 数字 整数 浮点数 复数 字符串 布尔 复合类型 数据 结构体 引用类型 指针 切片 字典 函数 通道 接口类型 在此章节中先介绍基础类型 ...

  9. 进击的Python【第十七章】:jQuery的基本应用

    进击的Python[第十七章]:jQuery的基本应用

随机推荐

  1. 威佐夫博弈(Wythoff Game)

    有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者. ...

  2. Windows远程连接Linux

    目录 xrdp方式 vnc方式 xrdp方式 ----------------------------------------------------------------------------- ...

  3. 单例模式中用volatile和synchronized来满足双重检查锁机制

    背景:我们在实现单例模式的时候往往会忽略掉多线程的情况,就是写的代码在单线程的情况下是没问题的,但是一碰到多个线程的时候,由于代码没写好,就会引发很多问题,而且这些问题都是很隐蔽和很难排查的. 例子1 ...

  4. 比较.NET程序集(DLL或EXE)是否相同

    如何比较两个.NET程序集(DLL或EXE)是否相同呢? 直接比较文件内容?当然没那么简单了,这个你可以去试试,去比较一下两次Build产生的程序集, 就算内容没有改变,产生的程序集的二进制文件也是不 ...

  5. iOS dealloc 不被调用的问题

    最近项目中老是无缘无故的出现一下奔溃.查看一下堆栈信息,指针的指向都有,但还是奔溃.所以第一个怀疑出现野指针引起的问题.然后调试代码中的一下dealloc函数.好多对象在释放之后都没掉用.顿时吓出一身 ...

  6. windows CMD下的命令

    1.  dir 列出当前目录的内容 2.  切换目录 C:\Users\shuyun>e: ## 切换主目录 E:\>cd DataCenter ## cd 切换子目录 E:\DataCe ...

  7. div的水平和垂直居中

    CSS实现div的水平居中 div的水平居中可以通过margin设置为0 auto实现. .myDiv { width: 200px; height: 100px; margin: 0 auto; } ...

  8. js修改伪类的值

    css文件 p.change:after { content: attr(data-content); } js文件 $(this).addClass('change').attr('data-con ...

  9. RabbitMQ 集群之镜像同步

    mirrored 在上个博文中讲到了如果做集群,那么集群是成功了,但是queue是如何存放的呢?消息又是怎么同步呢. 默认的,也就是什么也不配置,直接在某个节点中添加一个queue,那么它仅仅是属于这 ...

  10. Python Logging模块的简单使用

    前言 日志是非常重要的,最近有接触到这个,所以系统的看一下Python这个模块的用法.本文即为Logging模块的用法简介,主要参考文章为Python官方文档,链接见参考列表. 另外,Python的H ...