博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C和指针 第十七章 经典数据类型 堆栈 队列 二叉树
阅读量:5030 次
发布时间:2019-06-12

本文共 8322 字,大约阅读时间需要 27 分钟。

堆栈:

//// Created by mao on 16-9-16.//#ifndef UNTITLED_STACK_H#define UNTITLED_STACK_H#define TRUE 1#define FALSE 0typedef 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 
#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 
#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 
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 
#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 
#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 
#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 
#include
#include
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 
#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

运行:

 

转载于:https://www.cnblogs.com/yangxunwu1992/p/5877908.html

你可能感兴趣的文章
hadoop2.2.0_hbase0.96_zookeeper3.4.5全分布式安装文档下载
查看>>
Flutter 贝塞尔曲线切割
查看>>
golang 的编译安装以及supervisord部署
查看>>
阿里架构师,讲述基于微服务的软件架构模式
查看>>
Eclipse导入maven项目时,Pom.xml文件报错处理方法
查看>>
01、JAVA开发准备
查看>>
asp.net mvc 错误处理 - 自定义报错处理,生成错误日志
查看>>
Linux centos ssh
查看>>
R语言之避免for循环示例
查看>>
[转]jQuery 选择器和dom操作
查看>>
Jenkins+Maven+SVN快速搭建持续集成环境(转)
查看>>
bootstrap 媒体查询
查看>>
杜教筛
查看>>
《Ext JS模板与组件基本知识框架图----模板》
查看>>
txmpp
查看>>
微信开发时调用jssdk,在安卓设备中成功调用;在ios设备中返回错误消息:config fail,无其他具体错误消息,且接口权限显示获取ok,无法调用...
查看>>
【Github教程】史上最全github使用方法:github入门到精通
查看>>
抽象工厂模式(Abstract Factory)
查看>>
luogu1373 小a和uim之大逃离 (dp)
查看>>
Redis的Pub/Sub客户端实现
查看>>