本文主要探讨队列和二叉树的相关知识。
队列
队列结构:队头指针指向队头元素,队尾指针指向队尾元素(链表形式或数组形式)
队列特特点:先进先出,对头插入,队尾出队
双端队列:对头队尾都可插入和出队
二叉树
二叉树:包含根节点和子节点,一个三角组内只有一个根节点,最多有两个子节点,也可无子节点,子节点和根节点存在某种关系
二叉树一般用链式存储包含两个子节点指针(左右),根结点指针和父节点指针
完全二叉树:从根结点起从上往下、从左往右依次存储
demo:
链式队列
pro.c
#include <stdio.h>
#include <stdlib.h>#include "queue.h"#define QUEUE_LEN 5int main()
{QUEUE *q = (QUEUE *)malloc(sizeof(QUEUE));int i;init_queue(q,QUEUE_LEN);//测试队列添加for (i = 0;i < 7; i++){push_queue(q,i);printf_queue(q);printf("head : %d, tail : %d,queue size : %d\n",get_head(q),get_tail(q),q->size);}//测试队列删除及删除后再添加for (i = 0;i < 7; i++){pop_queue(q);printf_queue(q);if(q->size)printf("head : %d, tail : %d,queue size : %d\n",get_head(q),get_tail(q),q->size);}for (i = 0;i < 7; i++)push_queue(q,i);printf_queue(q);printf("head : %d, tail : %d,queue size : %d\n",get_head(q),get_tail(q),q->size);//测试队列清空及清空后再添加clean_queue(q);if(q->size)printf("head : %d, tail : %d,queue size : %d\n",get_head(q),get_tail(q),q->size);printf_queue(q);for (i = 0;i < 7; i++)push_queue(q,i);printf_queue(q);printf("head : %d, tail : %d,queue size : %d\n",get_head(q),get_tail(q),q->size);return 0;
}
queue.h
#include <stdbool.h>typedef struct node
{int data;struct node *next;
} NODE;typedef struct queue
{NODE *head;NODE *tail;int size;int capacity; //队列容量
} QUEUE;//初始化队列
void init_queue(QUEUE *q,int capacity);//入队
void push_queue(QUEUE *q,int data);//出队
void pop_queue(QUEUE *q);//获取对头
int get_head(QUEUE *q);//获取队尾
int get_tail(QUEUE *q);//判断队满,队满为ture
bool queue_full(QUEUE *q);//判断队空,队空为ture
bool queue_empty(QUEUE *q);//打印队列
void printf_queue(QUEUE *q);//清空队列
void clean_queue(QUEUE *q);
queue.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>#include "queue.h"void init_queue(QUEUE *q,int capacity)
{q->head = q->tail = (NODE *)malloc(sizeof(NODE));assert(q->head != NULL);q->head->next = NULL;q->size = 0;q->capacity = capacity; return;
}void push_queue(QUEUE *q,int data)
{if(queue_full(q)){printf("queue full\n");return;}NODE *p = (NODE *)malloc(sizeof(NODE));assert(p != NULL);p->data = data;p->next = NULL;q->tail->next = p;q->tail = p;(q->size)++;return;
}void pop_queue(QUEUE *q)
{if(queue_empty(q)){printf("queue empty\n");return;}NODE *p = q->head;q->head = p->next;free(p);(q->size)--;return;
}int get_head(QUEUE *q)
{if(queue_empty(q)){printf("queue empty\n");return;}return q->head->next->data;
}int get_tail(QUEUE *q)
{if(queue_empty(q)){printf("queue empty\n");return;}return q->tail->data;
}bool queue_full(QUEUE *q)
{return (q->size == q->capacity);
}bool queue_empty(QUEUE *q)
{return (q->size == 0);
}void printf_queue(QUEUE *q)
{if(queue_empty(q)){printf("queue empty\n");return;}NODE *p = q->head;p = p->next;while(p != NULL){printf("%d ",p->data);p = p->next;}printf("\n");return;
}void clean_queue(QUEUE *q)
{if(queue_empty(q)){printf("queue empty\n");return;}NODE *p = q->head;NODE *tmp;p = p->next;while(p != NULL){tmp = p;p = p->next;free(tmp);}free(q->head);q->size = 0;return;
}
结果示例:
二叉树
pro.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>#include "tree.h"#define TREE_SIZE 50void insert(TREE *t)
{init_tree(t,TREE_SIZE);insert_tree(t,20);insert_tree(t,15);insert_tree(t,30);insert_tree(t,10);insert_tree(t,17);insert_tree(t,1);insert_tree(t,35);insert_tree(t,25);
}int main()
{TREE *t = (TREE *)malloc(sizeof(TREE));assert(t != NULL);insert(t);printf_tree(t->root);printf("\n");NODE *p = NULL;p = find_tree_node(t,1);if(p != NULL)printf("find result: %d\n",p->data);clean_tree(t);printf_tree(t->root);printf("\n");insert(t);printf_tree(t->root);printf("\n");delete_tree_node(t,17);printf_tree(t->root);printf("\n");delete_tree_node(t,10);printf_tree(t->root);printf("\n");delete_tree_node(t,30);printf_tree(t->root);printf("\n");delete_tree_node(t,35);printf_tree(t->root);printf("\n");delete_tree_node(t,20);printf_tree(t->root);printf("\n");return 0;
}
tree.h
#include <stdbool.h>typedef struct node
{int data;struct node *parent; //父节点struct node *left; //左子节点struct node *right; //右子节点
} NODE;typedef struct tree
{NODE *root; //根节点int size; //树节点个数int capacity; //树节点数限制
} TREE;//初始化树
void init_tree(TREE *t,int capacity);//判断树为空
bool tree_emputy(TREE *t);//判断树满
bool tree_full(TREE *t);//获取树节点个数
int get_tree_size(TREE *t);//插入节点
void insert_tree(TREE *t,int data);//遍历树
void printf_tree(NODE *n);//清空树
void clean_tree(TREE *t);//查找树节点
NODE *find_tree_node(TREE *t,int data);//删除树节点
void delete_tree_node(TREE *t,int data);
tree.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>#include "tree.h"void init_tree(TREE *t,int capacity)
{t->root = NULL;t->size = 0;t->capacity = capacity;return;
}bool tree_emputy(TREE *t)
{return (t->size == 0);
}bool tree_full(TREE *t)
{return (t->size == t->capacity);
}int get_tree_size(TREE *t)
{return t->size;
}static NODE *create_node(int data)
{NODE *p = malloc(sizeof(NODE));assert(p != NULL);p->data = data;p->left = p->right = p->parent = NULL;return p;
}static NODE *add_left(NODE *n,NODE *p)
{NODE *tmp = n;if(p->data < tmp->data){if(tmp->left == NULL){tmp->left = p;p->parent = tmp;return NULL;}}return tmp->left;
}static NODE *add_right(NODE *n,NODE *p)
{NODE *tmp = n;if(p->data > tmp->data){if(tmp->right == NULL){tmp->right = p;p->parent = tmp;return NULL;}}return tmp->right;
}static void add_tree(TREE *t,NODE *p)
{NODE *tmp = t->root;while(1){if(p->data == tmp->data){printf("%d is excited\n",p->data);return;}else if(p->data > tmp->data){if(!(tmp = add_right(tmp,p)))break;}else{if(!(tmp = add_left(tmp,p)))break;}}t->size++;return;
}void insert_tree(TREE *t,int data)
{TREE *tmp = t;if(tree_full(tmp)){printf("tree full\n");return;}NODE *p = create_node(data);if(tmp->root == NULL){tmp->root = p;tmp->size++;return;}add_tree(tmp,p);return;
}void printf_tree(NODE *n)
{//中序:左根右if(n == NULL)return;printf_tree(n->left);printf("%d ",n->data);printf_tree(n->right);
/*//左序:根左右if(n == NULL)return;printf("%d ",n->data);printf_tree(n->left);printf_tree(n->right);//右序:左右根if(n == NULL)return;printf_tree(n->left);printf_tree(n->right);printf("%d ",n->data);
*/
}static clean_node(NODE *n)
{if(n != NULL){clean_node(n->left);clean_node(n->right);free(n);}
}void clean_tree(TREE *t)
{clean_node(t->root);t->root = NULL;t->size = 0;
}static NODE *find_node(NODE *p,int data)
{while(1){if(p->data == data)return p;if(p->data > data)p = p->left;if(p->data < data)p = p->right;}
}NODE *find_tree_node(TREE *t,int data)
{if(tree_emputy(t)){printf("tree emputy\n");return NULL;}NODE *tmp = NULL;tmp = find_node(t->root,data);return tmp;
}int get_node_size(TREE *t)
{return t->size;
}static delete_leaf(NODE *p)
{if(p->parent->right == p){p->parent->right = NULL;}else{p->parent->left = NULL;}free(p);
}static void delete_single(NODE *p)
{if(p->parent->left == p){if(p->left != NULL){p->parent->left = p->left;p->left->parent = p->parent;}else{p->parent->left = p->right;p->right->parent = p->parent;}}else{if(p->left != NULL){p->parent->right = p->left;p->left->parent = p->parent;}else{p->parent->right = p->right;p->right->parent = p->parent;}}free(p);return;
}static NODE *find_pos(NODE *p)
{while(1){if(p->right != NULL){p = p->right;}else{return p;}}
}static void delete_both(TREE *t,NODE *p)
{NODE *left_pos;left_pos = find_pos(p->left);left_pos->right = p->right;p->right->parent = left_pos;if(p == t->root){t->root = t->root->left;}else{if(p->parent->left == p){p->parent->left = p->left;p->left->parent = p->parent; }else{p->parent->right = p->left;p->left->parent = p->parent;}}free(p);return;
}static void delete_node(TREE *t,NODE *p)
{if(p->right == NULL && p->left == NULL){delete_leaf(p);}else if(p->right != NULL && p->left != NULL){delete_both(t,p);}else{delete_single(p);}
}void delete_tree_node(TREE *t,int data)
{if(tree_emputy(t)){printf("tree emputy\n");return;}NODE *tmp = find_tree_node(t,data);if(!tmp){printf("tree emputy or data is not excited\n");}delete_node(t,tmp);t->size--;return;
}
结果示例: