日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构之树的一些基本操作

發布時間:2023/12/19 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构之树的一些基本操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

是由根結點和若干顆子樹構成的。樹是由一個集合以及在該集合上定義的一種關系構成的。集合中的元素稱為樹的結點,所定義的關系稱為父子關系。父子關系在樹的結點之間建立了一個層次結構。在這種層次結構中有一個結點具有特殊的地位,這個結點稱為該樹的根結點,或稱為樹根。
頭文件 tree.h

#ifndef __TREE_H__ #define __TREE_H__#include "error.h"struct _treeNode; // 結構體聲明// 孩子結點鏈表的類型 typedef struct _childNode {struct _treeNode * childNode;struct _childNode* next; // 指向孩子結點鏈表下一個元素 }ChildNode;// 樹節點類型 typedef char TreeData; typedef struct _treeNode {TreeData data;struct _treeNode * parent; // 指向父節點的指針struct _treeNode * next; // 指向鏈表的下一個結點struct _childNode* childList; // 孩子鏈表的頭節點int degree; // 結點的度 }TreeNode;typedef struct _tree {struct _treeNode* head; // 樹鏈表的頭節點int len; // 樹結點個數 }Tree;// 定義一個函數指針類型 typedef void(*TreePrint)(TreeNode *node);Tree* Create_Tree();// pos 代表要插入結點父親結點的位置 // 約定: // 1 新插入的結點插入在當前父親結點所有孩子的右邊 // 2 根節點的位置是 0 int Insert_Tree (Tree* tree, TreeData data, int pos);// 打印樹 void Display (Tree* tree, TreePrint pFunc);// 刪除結點 int Delete (Tree* tree, int pos, TreeData *x);// 求指定位置樹結點的值 int Tree_Get (Tree* tree, int pos, TreeData *x);// 清空樹中所有的節點 int Tree_Clear (Tree* tree);// 樹的銷毀 void Tree_Destroy (Tree* tree);// 獲取根節點的地址 TreeNode* Tree_Root (Tree* tree);// 求樹的結點個數 int Tree_Count (Tree* tree);// 求樹的高度 int Tree_Height (Tree* tree);// 求樹的度 int Tree_Degree (Tree* tree);// 打印 void printA (TreeNode* node);#endif // __TREE_H__

源文件 tree.c

#include "tree.h" #include <stdlib.h>Tree *Create_Tree() {// 創建樹節點Tree* tree = (Tree*) malloc(sizeof(Tree)/sizeof(char));if (NULL == tree){errno = MALLOC_ERROR;return NULL;}// 給樹結點鏈表創建頭節點tree->head = (TreeNode*) malloc(sizeof(TreeNode)/sizeof(char));if (NULL == tree->head){errno = MALLOC_ERROR;free (tree);return NULL;}tree->head->parent = NULL;tree->head->childList = NULL;tree->head->next = NULL; // 代表樹中沒有結點// 空樹結點為0tree->len = 0;return tree; }int Insert_Tree (Tree* tree, TreeData data, int pos) {if (NULL == tree || pos < 0 || pos > tree->len){errno = ERROR;return FALSE;}if (pos != 0 && tree->len == pos){errno = ERROR;return FALSE;}// 新建結點TreeNode* node = (TreeNode*) malloc(sizeof(TreeNode)/sizeof(char));if (NULL == node){ errno = MALLOC_ERROR;return FALSE;}node->data = data;node->next = NULL;// 創建該新節點的孩子結點鏈表的頭節點node->childList = (ChildNode*) malloc(sizeof(ChildNode)/sizeof(char));if (NULL == node->childList){ errno = MALLOC_ERROR;free (node);return FALSE;} node->childList->next = NULL;node->childList->childNode = NULL;node->degree = 0;int i;// 找父節點TreeNode* parent = tree->head->next; // 當前樹節點的第一個結點for (i = 0; i < pos; i++){parent = parent->next;}node->parent = parent; // 在父親結點的子結點鏈表中加入一個結點if (parent != NULL){// 創建一個孩子結點ChildNode* childnode = (ChildNode*) malloc(sizeof(ChildNode)/sizeof(char));if (NULL == childnode){errno = MALLOC_ERROR;free (node->childList);free (node);return FALSE;}childnode->childNode = node;childnode->next = NULL;// 加入到父親結點子結點鏈表當中ChildNode* tmp = parent->childList; // 子結點鏈表的頭節點while (tmp->next){ tmp = tmp->next;}tmp->next = childnode;parent->degree += 1;}TreeNode* tmp = tree->head; // 樹節點鏈表的頭節點while (tmp->next){tmp = tmp->next;}tmp->next = node;tree->len += 1;return TRUE; }// 遞歸打印結點 void r_display (TreeNode* node, int gap, TreePrint pFunc) {if (NULL == node){return;}// 打印距離前一個結點的距離int i;for (i = 0; i < gap; i++){printf ("%c", '-');}// 打印結點自己// printf ("%c\n", node->data);pFunc (node);ChildNode* child = node->childList->next; // 該結點的第一個孩子// 打印該結點的孩子while (child){r_display (child->childNode, gap+4, pFunc);child = child->next; // 下一個孩子} }void Display (Tree *tree, TreePrint pFunc) {if (NULL == tree){return;}r_display (tree->head->next, 0, pFunc); }void r_delete (Tree *tree, TreeNode *node) {if (NULL == tree || NULL == node)return;// 從樹鏈表中移除這個結點,找node的前一個結點TreeNode* tmp = tree->head; // 鏈表的頭節點while (tmp->next){if (tmp->next == node){tmp->next = node->next;tree->len--;break;}tmp = tmp->next;}// 將父親結點中子結點鏈表中指向node的結點刪除TreeNode* parent = node->parent;if (NULL != parent){ChildNode* tmp = parent->childList; // 子結點鏈表的頭節點while (tmp->next){if (tmp->next->childNode == node){ChildNode* p = tmp->next;tmp->next = p->next;free (p);parent->degree--;break;}tmp = tmp->next;}}// 將該結點的孩子結點刪掉ChildNode* child = node->childList->next; // 子結點鏈表中的第一個結點while (child){ChildNode* pchild = child->next;r_delete (tree, child->childNode);child = pchild;}free (node->childList);free (node); }int Delete (Tree *tree, int pos, TreeData *x) {if (NULL == tree || pos < 0 || pos > tree->len){errno = ERROR;return FALSE;}if (0 != pos && tree->len == pos){errno = ERROR;return FALSE;}int i;// 找結點TreeNode* current = tree->head->next; for (i = 0; i < pos; i++){current = current->next;}*x = current->data;r_delete (tree, current);return TRUE;}int Tree_Get (Tree* tree, int pos, TreeData *x) {if (NULL == tree || pos < 0 || pos > tree->len){errno = ERROR;return FALSE;}if (0 != pos && tree->len == pos){errno = ERROR;return FALSE;}int i;// 找結點TreeNode* current = tree->head->next; for (i = 0; i < pos; i++){current = current->next;}*x = current->data;return TRUE; }int Tree_Clear (Tree* tree) {if (NULL == tree){errno = ERROR;return FALSE;}TreeData x;return Delete (tree, 0, &x); }void Tree_Destroy (Tree* tree) {if (NULL == tree){errno = ERROR;return;}Tree_Clear (tree);free (tree->head);free (tree); }TreeNode* Tree_Root (Tree* tree) {if (NULL == tree){errno = ERROR;return NULL;}return tree->head->next; }int Tree_Count (Tree* tree) {if (NULL == tree){errno = ERROR;return FALSE;}return tree->len; }// 遞歸求高度 int r_height (TreeNode* node) {if (NULL == node){return 0;}int subHeight = 0;int max = 0;ChildNode* child = node->childList->next;while (child){subHeight = r_height (child->childNode);if (subHeight > max){max = subHeight;}child = child->next;}return max + 1; }int Tree_Height (Tree* tree) {if (NULL == tree){errno = ERROR;return FALSE;}int height = r_height (tree->head->next);return height; }// 遞歸求度 int r_degree (TreeNode* node) {if (NULL == node){return 0;}int max = node->degree;int subDegree = 0;ChildNode* child = node->childList->next;while (child){subDegree = r_degree (child->childNode);if (subDegree > max){max = subDegree;}child = child->next;}return max; }int Tree_Degree (Tree* tree) {if (NULL == tree){errno = ERROR;return FALSE;}int degree = r_degree (tree->head->next);return degree; }void printA (TreeNode* node) {printf ("%c\n", node->data); }

主函數 main.c

#include <stdio.h> #include "tree.h"int main() {Tree* tree = Create_Tree();if (NULL == tree){myError ("Create_Tree");return -1;}Insert_Tree (tree, 'A', 0);Insert_Tree (tree, 'B', 0);Insert_Tree (tree, 'C', 0);Insert_Tree (tree, 'D', 0);Insert_Tree (tree, 'E', 1);Insert_Tree (tree, 'F', 1);Insert_Tree (tree, 'H', 3);Insert_Tree (tree, 'I', 3);Insert_Tree (tree, 'J', 3);Insert_Tree (tree, 'X', 3);Insert_Tree (tree, 'Z', 8);Display (tree, printA);//printf ("刪除B :\n");TreeData x;//Delete(tree, 1, &x);//Display(tree, printA);printf ("height = %d\n", Tree_Height(tree));printf ("degree = %d\n", Tree_Degree(tree));return 0; }

error.h是我自己寫的一個包含常見錯誤的頭文件,這里我就不發了。

總結

以上是生活随笔為你收集整理的数据结构之树的一些基本操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。