对于二叉树而言,有如下特性:
1.第i层上,最多有2^(i-1)个节点。
2.高度为k的二叉树,最多有2^k-1个节点。
3.假设叶子数目为n0,度为2的节点数目为n2,则有:n0= n2+1



1.二叉树的插入

#include <stdio.h>
#include <stdlib.h>
#include "drawtree.h"// 二叉树数据节点
typedef struct node
{int data;  // 数据域struct node *lchild;  //左子树指针struct node *rchild; //右子树指针
}node;//二叉树插入
node *bst_insert(node *root, int new_data);
// 前序遍历: 根节点 - 左子树 - 右子树
void pre_traval(node *root);
// 中序遍历:左子树 - 根节点 - 右子树
void mid_traval(node *root);
// 后序遍历:左子树 - 右子树 - 根节点
void lst_traval(node *root);int main()
{// 1.初始化空二叉树node *root = NULL;// 插入数据root = bst_insert(root, 10);root = bst_insert(root, 5);root = bst_insert(root, 15);root = bst_insert(root, 3);root = bst_insert(root, 8);root = bst_insert(root, 7);root = bst_insert(root, 9);root = bst_insert(root, 20);root = bst_insert(root, 18);// 2.数据操作int cmd;while(1){printf("Pls Input: ");scanf("%d", &cmd); while(getchar()!='\n');if(cmd != 0)   //二叉树插入root = bst_insert(root, cmd);else if(cmd == 0)    // 遍历{printf("pre_traval: ");pre_traval(root);    // 前序遍历printf("\n");printf("mid_traval: ");mid_traval(root);    // 中序遍历printf("\n");printf("lst_traval: ");lst_traval(root);    // 后序遍历printf("\n");}draw((_treenode *)root);}return 0;
}// 前序遍历: 根节点-左子树-右子树
void pre_traval(node *root)
{if(root == NULL)return;printf("%d ", root->data);pre_traval(root->lchild);pre_traval(root->rchild);
}// 中序遍历:左子树 - 根节点 - 右子树
void mid_traval(node *root)
{if(root == NULL)return;mid_traval(root->lchild);printf("%d ", root->data);mid_traval(root->rchild);
}// 后序遍历:左子树 - 右子树 - 根节点
void lst_traval(node *root)
{if(root == NULL)return;lst_traval(root->lchild);lst_traval(root->rchild);printf("%d ", root->data);
}//二叉树插入
node *bst_insert(node *root, int new_data)
{if(root == NULL){// 如果当前根节点为NULL,说明找到了插入位置node *new = malloc(sizeof(node));new->data = new_data;new->lchild = NULL;new->rchild = NULL;return new;}else if(root->data > new_data)   // 如果新数据更小,往左子树插入root->lchild = bst_insert(root->lchild, new_data);else if(root->data < new_data)  // 如果新数据更大,往右子树插入root->rchild = bst_insert(root->rchild, new_data);else  // 如果相等,已存在,不作处理printf("已存在\n");return root;
}

2.二叉树查找

#include <stdio.h>
#include <stdlib.h>
#include "drawtree.h"// 二叉树数据节点
typedef struct node
{int data;  // 数据域struct node *lchild;  //左子树指针struct node *rchild; //右子树指针
}node;//二叉树插入
node *bst_insert(node *root, int new_data);
// 二叉树搜索
int bst_search(node *root, int find_data);
// 前序遍历: 根节点 - 左子树 - 右子树
void pre_traval(node *root);
// 中序遍历:左子树 - 根节点 - 右子树
void mid_traval(node *root);
// 后序遍历:左子树 - 右子树 - 根节点
void lst_traval(node *root);int main()
{// 1.初始化空二叉树node *root = NULL;// 插入数据root = bst_insert(root, 10);root = bst_insert(root, 5);root = bst_insert(root, 15);root = bst_insert(root, 3);root = bst_insert(root, 8);root = bst_insert(root, 7);root = bst_insert(root, 9);root = bst_insert(root, 20);root = bst_insert(root, 18);// 2.数据操作int cmd;while(1){printf("Pls Input find_data: ");scanf("%d", &cmd); while(getchar()!='\n');if(cmd != 0) //二叉树搜索{if(bst_search(root, cmd) == 0)printf("找到了\n");elseprintf("无此数据\n");}else if(cmd == 0)   // 遍历{printf("pre_traval: ");pre_traval(root);    // 前序遍历printf("\n");printf("mid_traval: ");mid_traval(root);    // 中序遍历printf("\n");printf("lst_traval: ");lst_traval(root);    // 后序遍历printf("\n");}draw((_treenode *)root);}return 0;
}// 二叉树搜索
int bst_search(node *root, int find_data)
{if(root == NULL) // 无此数据return -1;printf("find\n");if(root->data == find_data)    // 找到指定数据return 0;else if(find_data < root->data)return bst_search(root->lchild, find_data);else if(find_data > root->data)return bst_search(root->rchild, find_data);
}// 前序遍历: 根节点-左子树-右子树
void pre_traval(node *root)
{if(root == NULL)return;printf("%d ", root->data);pre_traval(root->lchild);pre_traval(root->rchild);
}// 中序遍历:左子树 - 根节点 - 右子树
void mid_traval(node *root)
{if(root == NULL)return;mid_traval(root->lchild);printf("%d ", root->data);mid_traval(root->rchild);
}// 后序遍历:左子树 - 右子树 - 根节点
void lst_traval(node *root)
{if(root == NULL)return;lst_traval(root->lchild);lst_traval(root->rchild);printf("%d ", root->data);
}//二叉树插入
node *bst_insert(node *root, int new_data)
{if(root == NULL){// 如果当前根节点为NULL,说明找到了插入位置node *new = malloc(sizeof(node));new->data = new_data;new->lchild = NULL;new->rchild = NULL;return new;}else if(root->data > new_data)   // 如果新数据更小,往左子树插入root->lchild = bst_insert(root->lchild, new_data);else if(root->data < new_data)  // 如果新数据更大,往右子树插入root->rchild = bst_insert(root->rchild, new_data);else  // 如果相等,已存在,不作处理printf("已存在\n");return root;
}

drawtree.h

///
//
//  Copyright(C), 2013-2017, GEC Tech. Co., Ltd.
//
//  文件: lab/tree/headers/drawtree.h
//  日期: 2017-9
//  描述: 使用C语言写一页webpage展示二叉树
//
//  作者: Vincent Lin (林世霖)   微信公众号:秘籍酷
//  技术微店: http://weidian.com/?userid=260920190
//  技术交流: 260492823(QQ群)
//
///#ifndef _DRAWTREE_H_
#define _DRAWTREE_H_/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 公共头文件 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <errno.h>#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <semaphore.h>
#include <fcntl.h>#include <pthread.h>
/* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 公共头文件 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */#define MAX(a, b) ({ \typeof(a) _a = a; \typeof(b) _b = b; \(void)(&_a == &_b);\_a > _b? _a : _b; \})/* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 默认二叉树节点 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
typedef struct _tree_node
{int data;struct _tree_node *lchild;struct _tree_node *rchild;#ifdef AVLint height;
#endif#ifdef RBstruct _tree_node *parent;int color;
#endif
}_treenode, *_linktree;
/* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 默认二叉树节点 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ *//* ↓↓↓↓↓ 用户指定二叉树节点 ↓↓↓↓↓ */
#ifndef NODE
#define NODE _treenode
#endif
/* ↑↑↑↑↑ 用户指定二叉树节点 ↑↑↑↑↑ *//* ↓↓↓↓↓↓↓↓↓↓↓↓↓ 画网页相关算法代码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */#ifndef QUEUE_NODE_DATATYPE
#define QUEUE_NODE_DATATYPE NODE *
#endiftypedef QUEUE_NODE_DATATYPE qn_datatype;struct _queue_node
{qn_datatype data;struct _queue_node *next;};typedef struct
{struct _queue_node *front;struct _queue_node *rear;
#ifdef QUEUE_SIZEint size;
#endif
}_queuenode, *_linkqueue;static _linkqueue init_queue(void)
{_linkqueue q = (_linkqueue)malloc(sizeof(_queuenode));q->front = q->rear =(struct _queue_node *)malloc(sizeof(struct _queue_node));q->rear->next = NULL;return q;
}static bool is_empty_q(_linkqueue q)
{return (q->front == q->rear);
}/* ↓↓↓↓↓↓↓↓↓↓↓↓↓ 画网页相关算法代码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
static bool out_queue(_linkqueue q, qn_datatype *pdata)
{if(is_empty_q(q))return false;struct _queue_node *p = q->front;q->front = q->front->next;free(p);*pdata = q->front->data;return true;
}static bool en_queue(_linkqueue q, qn_datatype data)
{struct _queue_node *pnew;pnew = (struct _queue_node *)malloc(sizeof(struct _queue_node));if(pnew == NULL)return false;pnew->data = data;pnew->next = NULL;q->rear->next = pnew;q->rear = pnew;return true;
}#ifdef QUEUE_SIZE
int queue_size(_linkqueue *q)
{return q->size;
}
#endif
/* ↓↓↓↓↓↓↓↓↓↓↓↓↓ 画网页相关算法代码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */static inline void pre_travel(NODE *root, void (*handler)(NODE *))
{if(root == NULL)return;handler(root);pre_travel(root->lchild, handler);pre_travel(root->rchild, handler);
}static inline void mid_travel(NODE *root, void (*handler)(NODE *))
{if(root == NULL)return;mid_travel(root->lchild, handler);handler(root);mid_travel(root->rchild, handler);
}static inline void post_travel(NODE *root, void (*handler)(NODE *))
{if(root == NULL)return;post_travel(root->lchild, handler);post_travel(root->rchild, handler);handler(root);
}/* ↓↓↓↓↓↓↓↓↓↓↓↓↓ 画网页相关算法代码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
static inline void level_travel(NODE *root, void (*handler)(NODE *))
{if(root == NULL)return;_linkqueue q;q = init_queue();en_queue(q, root);NODE *tmp;while(1){if(!out_queue(q, &tmp))break;handler(tmp);if(tmp->lchild != NULL)en_queue(q, tmp->lchild);if(tmp->rchild != NULL)en_queue(q, tmp->rchild);}
}
/* ↓↓↓↓↓↓↓↓↓↓↓↓↓ 画网页相关算法代码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
static char page_begin[] = "<html><head><title>tree map""</title></head><body>""<table border=0 cellspacing""=0 cellpadding=0>";
static char line_begin[] = "<tr>";
static char line_end  [] = "</tr>";
static char space     [] = "<td>&nbsp;</td>";
static char underline [] = "<td style=\"border-bottom:""1px solid #58CB64\">&nbsp;""</td>";#ifdef RB
static char data_begin_red[] = "<td bgcolor=\"#FF0000\";style=""\"border:1px sol""id #58CB64;background-colo""r:#DDF1D8;PADDING:2px;\" t""itle=\"level: 1\">";
static char data_begin_blk[] = "<td bgcolor=\"#000000\";style=""\"border:1px sol""id #58CB64;background-colo""r:#DDF1D8;PADDING:2px;\" t""itle=\"level: 1\"><font color""=\"#FFFFFF\">";
static char data_end_red[] = "</td>";
static char data_end_blk[] = "</font></td>";
#else
static char data_begin[] = "<td style=\"border:1px sol""id #58CB64;background-colo""r:#DDF1D8;PADDING:2px;\" t""itle=\"level: 1\">";
static char data_end  [] = "</td>";
#endifstatic char page_end  [] = "</table></body></html>";#define MAX_NODES_NUMBER 100
#define FILENAME 32static int central_order[MAX_NODES_NUMBER];static void putunderline(int fd, int num)
{int i;for(i=0; i<num; i++){write(fd, underline, strlen(underline));}
}static void putspace(int fd, int num)
{int i;for(i=0; i<num; i++){write(fd, space, strlen(space));}
}
/* ↓↓↓↓↓↓↓↓↓↓↓↓↓ 画网页相关算法代码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
#ifdef RB
static void putdata(int fd, NODE * p)
{char s[50];bzero(s, 50);snprintf(s, 50, "%d", p->data);switch(p->color){case RED:write(fd, data_begin_red, strlen(data_begin_red));write(fd, s, strlen(s));write(fd, data_end_red, strlen(data_end_red));break;case BLACK:write(fd, data_begin_blk, strlen(data_begin_blk));write(fd, s, strlen(s));write(fd, data_end_blk, strlen(data_end_blk));}
}
#else
static void putdata(int fd, int data)
{char s[50];bzero(s, 50);snprintf(s, 50, "%d", data);write(fd, data_begin, strlen(data_begin));write(fd, s, strlen(s));write(fd, data_end, strlen(data_end));
}
#endifstatic int Index = 0;
static void create_index(NODE * root)
{if(Index >= MAX_NODES_NUMBER-1)return;central_order[Index++] = root->data;
}static int get_index(int data)
{int i;for(i=0; i<100; i++){if(central_order[i] == data)return i;}return -1;
}/* ↓↓↓↓↓↓↓↓↓↓↓↓↓ 画网页相关算法代码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
static void data_leftside(int fd, NODE * root, int spaces)
{if(root == NULL)return;int s_line=0;if(root->lchild != NULL){s_line = get_index(root->data)-get_index(root->lchild->data)-1;}putspace(fd, spaces-s_line);putunderline(fd, s_line);
}static int data_rightside(int fd, NODE * root)
{if(root == NULL)return 0;int s_line=0;if(root->rchild != NULL){s_line = get_index(root->rchild->data)-get_index(root->data)-1;}putunderline(fd, s_line);return s_line;
}static void start_page(int fd)
{write(fd, page_begin, strlen(page_begin));
}/* ↓↓↓↓↓↓↓↓↓↓↓↓↓ 画网页相关算法代码 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
static void end_page(int fd)
{write(fd, page_end, strlen(page_end));
}static void draw(NODE * root)
{if(root == NULL)return;time_t t;time(&t);static char filename[FILENAME];bzero(filename, FILENAME);snprintf(filename, FILENAME, "1.html");int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0644);if(fd == -1){perror("open() failed");exit(1);}Index = 0;mid_travel(root, create_index);_linkqueue q = init_queue();NODE * tmp = root;int ndata = 1;start_page(fd);while(1){write(fd, line_begin, strlen(line_begin));int i, n = 0;int nextline = 0;for(i=0; i<ndata; i++){int index = get_index(tmp->data);data_leftside(fd, tmp, index-n);#ifdef RBputdata(fd, tmp);#elseputdata(fd, tmp->data);#endifint rightline = data_rightside(fd, tmp);if(tmp->lchild != NULL){nextline++;en_queue(q, tmp->lchild);}if(tmp->rchild != NULL){nextline++;en_queue(q, tmp->rchild);}if(!out_queue(q, &tmp))return;n = index + rightline;n++;}write(fd, line_end, strlen(line_end));ndata = nextline;}end_page(fd);close(fd);
}
#endif


冒泡排序

#include <stdio.h>void show_array(int len, int *a)
{int i;for(i=0; i<len; i++)printf("%d ", a[i]);printf("\n");
}void bubble_sort(int len, int *a)
{// 遍历次数:len-1int i, j;int temp;int flag;for(i=0; i<len-1; i++){flag=0;// 两两对比,左数大于右数则交换(次数: len-i-1)for(j=0; j<len-i-1; j++){if(a[j] > a[j+1]){temp = a[j];a[j] = a[j+1];a[j+1] = temp;flag = 1;}}printf("%d: ", i+1);show_array(5, a);// 如果没有发生数据交换,则说明已经是有序列if(flag == 0)break;}
}int main()
{int arr[5] = {5, 4, 3, 2, 1};show_array(5, arr);bubble_sort(5, arr);show_array(5, arr);return 0;
}

插入排序-额外空间

#include <stdio.h>void show_array(int len, int *a)
{int i;for(i=0; i<len; i++)printf("%d ", a[i]);printf("\n");
}void insertion_sort(int len, int *a)
{// 1.定义有序列数组,将第1个数据放入int b[len];b[0] = a[0];// 2.将原始数据的每个数据与有序列中数据对比,找到插入位置posint i;        // 原始数据操作下标int j;       // 向后移动变量int pos;   // 有序列对比下标for(i=1; i<len; i++){// 2.1 在有序列中循环找到插入位置pos后,break结束for(pos=0; pos<i; pos++)  {if(a[i] < b[pos])break;}// 2.2 将pos后续数据向后移动(从最后开始)for(j=i; j>pos; j--)b[j] = b[j-1];// 2.3 数据放入有序列中pos位置b[pos] = a[i];// 把中间过程的数据打印出来printf("%d: ", i);show_array(5, b);}// 3.将有序列数据覆盖无序列for(i=0; i<len; i++)a[i] = b[i];
}int main()
{int arr[5] = {2, 5, 3, 1, 4};show_array(5, arr);insertion_sort(5, arr);show_array(5, arr);return 0;
}

插入排序

#include <stdio.h>void show_array(int len, int *a)
{int i;for(i=0; i<len; i++)printf("%d ", a[i]);printf("\n");
}void insertion_sort(int len, int *a)
{int swap;  //无序列数下标int pos;int i;// 逐个循环取得无序数for(swap=1; swap<len; swap++){// 1.暂存当前无序数int temp = a[swap];// 2.该无序数与有序列每个数据对比,找到插入位置posfor(pos=0; pos<swap; pos++){if(temp < a[pos])break;}// 3.将pos后续数据逐个向后移动(从后开始)int i;for(i=swap; i>pos; i--)a[i] = a[i-1];// 4.将该无序数写入有序列a[pos] = temp;}
}int main()
{int arr[5] = {2, 5, 3, 1, 4};show_array(5, arr);// 不使用额外内存insertion_sort(5, arr);show_array(5, arr);return 0;
}

数据结构4——linuxC(二叉树和排序算法)相关推荐

  1. 南京邮电大学数据结构实验四(各种排序算法)

    南邮数据结构实验报告四----各种排序算法 一.各类算法 (一)简单选择排序 (二)直接插入排序 (三)冒泡排序 (四)快速排序 (五)两路合并排序 (六)堆排序 二.全部排序整合+时间测试 三.算法 ...

  2. 数据结构常用的七种排序算法总结

    前言 排序算法在数据结构里属于最为重要的一部分,例如我们熟悉的冒泡.选择.插入.归并等,这些当初在第一次学习的时候,并没有很好的掌握,现在因为在备战考研,刚刚进行完数据结构的一轮简单复习在开始整理一轮 ...

  3. 【swjtu】数据结构实验6_二叉树的遍历算法

    实验内容及要求: 编写程序,用先序递归遍历法建立二叉树的二叉链表存储结构,然后输出其先序.中序.后序以及层次遍历结点访问次序.其中层次遍历的实现需使用循环队列.二叉树结点数据类型建议选用字符类型. 实 ...

  4. Python数据结构学习笔记——搜索与排序算法

    目录 一.搜索 (一)搜索的方法 (二)顺序搜索 (三)二分搜索 二.排序 内排序和外排序 (一)冒泡排序 (二)选择排序 (三)插入排序 (四)希尔排序 (五)归并排序 (六)快速排序 总结 一.搜 ...

  5. 数据结构(七)高级排序算法——归并、快速排序

    一.归并排序 1.排序原理 归并排序算法是一种利用了分治算法思想实现的排序算法,这种排序算法是基于有序数组合并的归并排序算法的基本思想就是:判断一个待排序序列的长度,只要这个待排序序列的长度是超过1的 ...

  6. 数据结构几种常见的排序算法

    学习过经典的冒泡排序算法后,我们将继续深入学习,了解更多算法排序 插入排序 直接插入排序 直接插入排序其基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,指导所有记录插 ...

  7. 数据结构:十大经典排序算法

    0算法概述 0.1算法分类 十种常见排序算法可以分为两大类: 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序. 非比较类排序:不通 ...

  8. 【数据结构】求二叉树深度的算法

    要求二叉树的深度,方法是先求出左子树的深度,再求出右子树的深度,二叉树的深度就是左子树的深度和右子树的深度中的最大值加1. 自然而然想到用后根遍历的思想实现 主要步骤如下: 若二叉树为空,则返回0值, ...

  9. 【数据结构初阶】八大排序算法+时空复杂度

    学会控制自己是人生的必修课 文章目录 一.插入排序 1.直接插入排序 2.希尔排序 二.选择排序 1.直接选择排序 2.堆排序(已经建好堆的基础之上) 三.交换排序(Swap) 1.冒泡排序(大学牲最 ...

最新文章

  1. java 循环赛问题,网球循环赛思路 - 分治法求解(无代码)
  2. SAP创建Web Service以及用ABAP调用
  3. jQuery使用ajaxStart()和ajaxStop()方法
  4. IE 中的一些脚本问题
  5. [js] 手写一个trim()的方法
  6. python解析xml文件选用模块_Python标准库系列之xml模块
  7. html 读取 vb,VB编程:vb读取textbox控件某一行的方法
  8. 启明星会议室预定系统 helpdesk系统等 登陆失败的问题与解决方法
  9. LR监控linux系统资源
  10. 安卓虚拟摄像头_谷歌AR新推强大功能:虚拟对象无缝嵌入,可与现实环境交互...
  11. WINDOS服务器安全设置
  12. windows主机加固(2)
  13. BatchNormalization 介绍
  14. 如何建立一个网站?规划、设计、目的、原则、宣传(一)
  15. pytorch下Numpy,Torch,Spicy,NetworkX及其他基本数据类型相关操作(持续更新)
  16. JavaScript 10个常见用法
  17. 0315 财经爬虫实战
  18. android跳一跳功能实现,Android 数字跳动显示的TextView实现
  19. “墨子号”量子科学实验卫星成果获克利夫兰奖
  20. VMware NSX-T Data Center 3.2.3 防火墙下载及安装部署

热门文章

  1. js获取当前URL、参数、端口、IP等信息
  2. 94. 二叉树的中序遍历
  3. 5G专网应用:机遇和挑战并存
  4. 日文半角转全角 java_java将日文半角片假名转成全角的方法
  5. 元宇宙核心技术--脑机接口
  6. 5.8 综合案例2.0-智能刷卡门禁系统(仅支持2.2以上版本)
  7. SpringBoot企业级应用实战
  8. Java支付宝支付(Alipay),支付接口,同步异步通知
  9. 论述c语言和java语言的区别,java语言和c语言的区别有哪些
  10. vue首次渲染全过程