C和指针 第十七章 经典数据类型 堆栈 队列 二叉树
堆栈:
- //
- // Created by mao on 16-9-16.
- //
- #ifndef UNTITLED_STACK_H
- #define UNTITLED_STACK_H
- #define TRUE 1
- #define FALSE 0
- typedef int STACK_TYPE;
- typedef struct stack{
- STACK_TYPE value;
- struct stack *next;
- } STACK;
- void create_stack();
- void destory_stack();
- void push(STACK_TYPE value);
- STACK_TYPE pop();
- int isEmpty();
- #endif //UNTITLED_STACK_H
stack.h
- //
- // Created by mao on 16-9-16.
- //
- #include <stdlib.h>
- #include "stack.h"
- static STACK *stack;
- void create_stack()
- {
- stack = (STACK *)malloc(sizeof(STACK));
- stack -> next = NULL;
- }
- void destory_stack()
- {
- STACK *pStack;
- while((pStack = stack -> next) != NULL){
- free(stack);
- stack = pStack;
- }
- }
- void push(STACK_TYPE value)
- {
- STACK *new = (STACK *)malloc(sizeof(STACK));
- new -> next = stack;
- new -> value = value;
- stack = new;
- }
- STACK_TYPE pop()
- {
- STACK_TYPE value = stack -> value;
- STACK *pStack = stack;
- stack = stack -> next;
- free(pStack);
- return value;
- }
- int isEmpty()
- {
- return stack -> next == NULL ? TRUE : FALSE;
- }
stack.c
- #include <stdio.h>
- #include "stack.h"
- int main()
- {
- //堆栈
- create_stack();
- push(10);
- push(20);
- push(30);
- pop();
- push(22);
- while(isEmpty() == FALSE){
- printf("%d \t", pop());
- }
- }
main.c
运行:
队列:
当使用数组作为队列时,如果只是一端插入一端弹出,那么当尾部没有空间时,便无法插入元素,一种解决方法是使用“环绕”数组,新元素可以存储到以前删除元素所留出来的空间中,这种方法称为循环数组。
循环数组有个问题,当队列为空,或者为满时,首位的下标是一样的,无法判断出此时队列的状态,所以在队列的rear后加一个空余的不使用的位置,用来判断队列的状态是满队列,还是空队列。
当为满队列时:
- (rear + 2) % QUEUE_SIZE = front
当为空队列时:
- (rear + 1) % QUEUE_SIZE = front
队列实现:
- //
- // Created by mao on 16-9-16.
- //
- #ifndef UNTITLED_QUEUE_H
- #define UNTITLED_QUEUE_H
- #define TRUE 1
- #define FALSE 0
- #define QUEUE_SIZE 100
- #define ARRAY_SIZE (QUEUE_SIZE + 1)
- typedef int QUEUE_TYPE;
- static QUEUE_TYPE queue[ARRAY_SIZE];
- static int front = 1;
- static int rear = 0;
- void Q_delete();
- QUEUE_TYPE Q_first();
- void Q_insert(QUEUE_TYPE value);
- int Q_isEmpty();
- int Q_isFull();
- #endif //UNTITLED_QUEUE_H
queue.h
- //
- // Created by mao on 16-9-16.
- //
- #include "queue.h"
- #include <assert.h>
- void Q_delete()
- {
- assert(Q_isEmpty() == FALSE);
- front = (front + 1) % QUEUE_SIZE;
- front = (front) % QUEUE_SIZE;
- }
- QUEUE_TYPE Q_first()
- {
- assert(Q_isEmpty() == FALSE);
- return queue[front];
- }
- //队列插入数据,rear++
- void Q_insert(QUEUE_TYPE value)
- {
- assert(Q_isFull() == FALSE);
- rear = (rear + 1) % QUEUE_SIZE;
- queue[(rear) % QUEUE_SIZE] = value;
- }
- int Q_isEmpty()
- {
- return (rear + 1) % QUEUE_SIZE == front ? TRUE: FALSE;
- }
- int Q_isFull()
- {
- return (rear + 2) % QUEUE_SIZE == front ? TRUE : FALSE;
- }
queue.c
- #include <stdio.h>
- #include "queue.h"
- int main()
- {
- //插入队列
- Q_insert(10);
- Q_insert(12);
- Q_delete();
- Q_insert(22);
- Q_insert(30);
- printf("%d\n", Q_first());
- Q_delete();
- printf("%d\n", Q_first());
- Q_delete();
- printf("%d\n", Q_first());
- Q_delete();
- return 1;
- }
main.c
运行:
二叉树:
- #ifndef UNTITLED_BINARYTREE_H
- #define UNTITLED_BINARYTREE_H
- #include <assert.h>
- #define TREE_TYPE int
- #define ARRAY_SIZE 100
- #define TREE_SIZE (ARRAY_SIZE + 1)
- TREE_TYPE TREE[TREE_SIZE] = {0};
- static unsigned int leftChild(unsigned int current)
- {
- return current * 2;
- }
- static unsigned int rightChild(unsigned int current)
- {
- return current * 2 + 1;
- }
- void insert(TREE_TYPE value)
- {
- unsigned int current = 1;
- while(TREE[current] != 0){
- if(value < TREE[current]){
- current = leftChild(current);
- }else{
- assert(TREE[current] != value);
- current = rightChild(current);
- }
- assert(current < TREE_SIZE);
- }
- TREE[current] = value;
- }
- TREE_TYPE *find(TREE_TYPE value)
- {
- unsigned int current = 1;
- while (current < TREE_SIZE && TREE[current] != value){
- if(value < TREE[current]){
- current = leftChild(current);
- }else if(value > TREE[current]){
- current = rightChild(current);
- }
- }
- if(current < TREE_SIZE){
- return TREE + current;
- }else{
- return 0;
- }
- }
- //根据指针计算数组下标
- static unsigned long getIndex(TREE_TYPE *ptr){
- assert(ptr >= TREE || ptr <= TREE + TREE_SIZE);
- return ptr - TREE;
- }
- //内置先遍历接口
- void pre_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
- {
- if(current < ARRAY_SIZE && TREE[current] != 0){
- callback(TREE[current]);
- pre_order_traverse(leftChild(current), callback);
- pre_order_traverse(rightChild(current), callback);
- }
- }
- //先序遍历
- void do_pre_traverse(void(*callback)(TREE_TYPE value))
- {
- pre_order_traverse(1, callback);
- }
- //中序遍历
- void mid_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
- {
- if(current < ARRAY_SIZE && TREE[current] != 0){
- mid_order_traverse(leftChild(current), callback);
- callback(TREE[current]);
- mid_order_traverse(rightChild(current), callback);
- }
- }
- void do_mid_order_traverse(void(*callback)(TREE_TYPE value))
- {
- mid_order_traverse(1, callback);
- }
- //后续遍历
- void after_order_traverse(unsigned int current, void(*callback)(TREE_TYPE value))
- {
- if(current < ARRAY_SIZE && TREE[current] != 0){
- after_order_traverse(leftChild(current), callback);
- after_order_traverse(rightChild(current), callback);
- callback(TREE[current]);
- }
- }
- void do_after_order_traverse(void(*callback)(TREE_TYPE value))
- {
- after_order_traverse(1, callback);
- }
- void print_tree(TREE_TYPE value)
- {
- printf("%d\t", value);
- }
- #endif //UNTITLED_BINARYTREE_H
BinaryTree.h
- #include <stdio.h>
- #include "BinaryTree.h"
- int main()
- {
- insert(20);
- insert(12);
- insert(5);
- insert(9);
- insert(16);
- insert(17);
- insert(25);
- insert(28);
- insert(26);
- insert(29);
- do_pre_traverse(print_tree);
- printf("\n");
- do_mid_order_traverse(print_tree);
- printf("\n");
- do_after_order_traverse(print_tree);
- return 1;
- }
main.c
运行:
数组形式存放二叉树,会导致内存空间的浪费,尤其是非对称的二叉树,会造成大量的数组空间闲置。通过链式二叉树可以解决数组不充分的问题
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- typedef int TREE_TYPE;
- typedef struct TREE_NODE {
- TREE_TYPE value;
- struct TREE_NODE *leftPtr;
- struct TREE_NODE *rightPtr;
- } TREE_NODE;
- //指向树的根节点的指针
- TREE_NODE *root;
- //创建根节点
- void createTree(TREE_TYPE value)
- {
- root = (TREE_NODE *) malloc(sizeof(TREE_NODE));
- root -> leftPtr = NULL;
- root -> rightPtr = NULL;
- root -> value = value;
- }
- TREE_NODE * getRoot()
- {
- return root;
- }
- //插入节点
- void insertNode(TREE_TYPE value)
- {
- TREE_NODE *current = root;
- //pos为待插入节点的父节点
- TREE_NODE *parent = root;
- while(current != NULL){
- //保存父节点信息
- parent = current;
- if(current -> value < value){
- current = current -> rightPtr;
- }else if(current -> value > value){
- current = current -> leftPtr;
- }else{
- //节点已存在
- return ;
- }
- }
- TREE_NODE *node = (TREE_NODE *) malloc(sizeof(TREE_NODE));
- assert(node != NULL);
- node -> leftPtr = NULL;
- node -> rightPtr = NULL;
- node -> value = value;
- //根据值得大小判断,node应该放在左节点还是右节点
- if(parent -> value > value){
- parent -> leftPtr = node;
- }else{
- parent -> rightPtr = node;
- }
- }
- TREE_NODE * findNode(TREE_TYPE value)
- {
- TREE_NODE *current = root;
- while(current != NULL && current -> value != value){
- if( current -> value > value){
- current = current -> leftPtr;
- }else{
- current = current -> rightPtr;
- }
- }
- return current;
- }
- void printNode(TREE_NODE * node)
- {
- printf("%d\t", node -> value);
- }
- void pre_order_traverse(TREE_NODE * current)
- {
- if(current != NULL){
- printNode(current);
- pre_order_traverse(current -> leftPtr);
- pre_order_traverse(current -> rightPtr);
- }
- }
- void mid_order_traverse(TREE_NODE * current)
- {
- if(current != NULL){
- mid_order_traverse(current -> leftPtr);
- printNode(current);
- mid_order_traverse(current -> rightPtr);
- }
- }
- void after_order_traverse(TREE_NODE * current)
- {
- if(current != NULL){
- after_order_traverse(current -> leftPtr);
- after_order_traverse(current -> rightPtr);
- printNode(current);
- }
- }
BinaryTree.h
- #include <stdio.h>
- #include "BinaryTree.h"
- int main()
- {
- createTree(20);
- insertNode(12);
- insertNode(5);
- insertNode(9);
- insertNode(16);
- insertNode(17);
- insertNode(25);
- insertNode(28);
- insertNode(26);
- insertNode(29);
- pre_order_traverse(root);
- printf("\n");
- mid_order_traverse(root);
- printf("\n");
- after_order_traverse(root);
- return 1;
- }
BinaryTree.c
运行:
C和指针 第十七章 经典数据类型 堆栈 队列 二叉树的更多相关文章
- C和指针 第十七章 习题
17.8 为数组形式的树编写模块,用于从树中删除一个值,如果没有找到,程序节点 ArrayBinaryTree.c // // Created by mao on 16-9-18. // #inclu ...
- C和指针 第十七章 二叉树删除节点
二叉树的节点删除分为三种情况: 1.删除的节点没有子节点,直接删除即可 2. 删除的节点有一个子节点,直接用子节点替换既可以 3.删除的节点有两个子节点. 对于第三种情况,一般是不删除这个节点,而是删 ...
- 第二十七章 system v消息队列(三)
消息队列实现回射客户/服务器 msg_srv.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> ...
- 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索
第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...
- Gradle 1.12 翻译——第十七章. 从 Gradle 中调用 Ant
有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...
- Linux内核设计第十七章笔记
第十七章 设备与模块 关于设备驱动和设备管理,四种内核成分 设备类型:在所有unix系统中为了统一普通设备的操作所采用的分类 模块:Linux内核中用于按需加载和卸载目标代码的机制 内核对象:内核数据 ...
- 【C++】《C++ Primer 》第十七章
第十七章 标准库特殊设施 一.tuple类型 tuple是类似pair的模板,每个pair的成员类型都不相同,但每个pair都恰好有两个成员. 不同的tuple类型的成员类型也不相同,一个tuple可 ...
- 《Go语言圣经》阅读笔记:第三章基础数据类型
第三章 基础数据类型 Go语言将数据类型分为四类: 基础类型 数字 整数 浮点数 复数 字符串 布尔 复合类型 数据 结构体 引用类型 指针 切片 字典 函数 通道 接口类型 在此章节中先介绍基础类型 ...
- 进击的Python【第十七章】:jQuery的基本应用
进击的Python[第十七章]:jQuery的基本应用
随机推荐
- 威佐夫博弈(Wythoff Game)
有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后把石子全部取完者为胜者. ...
- Windows远程连接Linux
目录 xrdp方式 vnc方式 xrdp方式 ----------------------------------------------------------------------------- ...
- 单例模式中用volatile和synchronized来满足双重检查锁机制
背景:我们在实现单例模式的时候往往会忽略掉多线程的情况,就是写的代码在单线程的情况下是没问题的,但是一碰到多个线程的时候,由于代码没写好,就会引发很多问题,而且这些问题都是很隐蔽和很难排查的. 例子1 ...
- 比较.NET程序集(DLL或EXE)是否相同
如何比较两个.NET程序集(DLL或EXE)是否相同呢? 直接比较文件内容?当然没那么简单了,这个你可以去试试,去比较一下两次Build产生的程序集, 就算内容没有改变,产生的程序集的二进制文件也是不 ...
- iOS dealloc 不被调用的问题
最近项目中老是无缘无故的出现一下奔溃.查看一下堆栈信息,指针的指向都有,但还是奔溃.所以第一个怀疑出现野指针引起的问题.然后调试代码中的一下dealloc函数.好多对象在释放之后都没掉用.顿时吓出一身 ...
- windows CMD下的命令
1. dir 列出当前目录的内容 2. 切换目录 C:\Users\shuyun>e: ## 切换主目录 E:\>cd DataCenter ## cd 切换子目录 E:\DataCe ...
- div的水平和垂直居中
CSS实现div的水平居中 div的水平居中可以通过margin设置为0 auto实现. .myDiv { width: 200px; height: 100px; margin: 0 auto; } ...
- js修改伪类的值
css文件 p.change:after { content: attr(data-content); } js文件 $(this).addClass('change').attr('data-con ...
- RabbitMQ 集群之镜像同步
mirrored 在上个博文中讲到了如果做集群,那么集群是成功了,但是queue是如何存放的呢?消息又是怎么同步呢. 默认的,也就是什么也不配置,直接在某个节点中添加一个queue,那么它仅仅是属于这 ...
- Python Logging模块的简单使用
前言 日志是非常重要的,最近有接触到这个,所以系统的看一下Python这个模块的用法.本文即为Logging模块的用法简介,主要参考文章为Python官方文档,链接见参考列表. 另外,Python的H ...