本文主要探讨队列和二叉树的相关知识。
队列
队列结构:队头指针指向队头元素,队尾指针指向队尾元素(链表形式或数组形式)
队列特特点:先进先出,对头插入,队尾出队
双端队列:对头队尾都可插入和出队
二叉树
二叉树:包含根节点和子节点,一个三角组内只有一个根节点,最多有两个子节点,也可无子节点,子节点和根节点存在某种关系
二叉树一般用链式存储包含两个子节点指针(左右),根结点指针和父节点指针
完全二叉树:从根结点起从上往下、从左往右依次存储
demo:
链式队列
pro.c
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
#define QUEUE_LEN 5
int 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 50
void 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;
}
结果示例: