1. 程式人生 > >資料結構—樹的實現(C語言)

資料結構—樹的實現(C語言)

1、樹的概念    樹形結構是節點之間以及分支關係定義的層次結構。作為一種重要的非線性結構,樹形結構中一個節點最多隻有一個前驅節點,但是可以有多個後繼節點。2、樹的儲存結構    在計算機中,樹有多種的儲存方式,下面介紹一種動態的“左子/右兄”二叉連結串列表示方法。
#include "mytree.h"
#include <vector>

using namespace std;

#define OK 		(0)
#define ERROR	(-1)

#define MAX_NAME_LEN (50) //最大的名字長度

/*樹結構體中資料成員*/
typedef struct _ElementType
{
	int id;
	char name[MAX_NAME_LEN];
}ElementType;

/*樹節點結構體*/
typedef struct _TreeNode
{
	int index;//結點的標識
	ElementType element;   //資料域
	struct _TreeNode *FirstChild; //第一個孩子指標	
	struct _TreeNode *NextSibing; //下一個兄弟 指標
}TreeNode;

/*樹結構體*/
typedef struct _CTree
{
	int num; //節點個數
	vector<int> nodeIndexs;//存放所有的結點index
	int rootIndex;//根節點的index
	TreeNode *root; //根節點指標
}CTree;

/*全域性資料儲存樹資訊*/
CTree g_tree;

/*
*    功能:檢測結點的index是否正確
*	 入參:要檢測的結點index
*	返回值:合法index返回true,不合法的index返回false
*/
static bool mytree_check_node_index(const int index)
{
	vector<int>::iterator it;

	for(it = g_tree.nodeIndexs.begin(); it != g_tree.nodeIndexs.end(); ++it )
	{
		if(*it == index)
		{
			return true;
		}
	}

	return false;
}

/*
*    功能:獲取指定的結點指標
*	 入參:父節點,比較引數index,出參nodeinfo
*	 返回值:NA
*/
void mytree_preorder_get_node(TreeNode *tree,	int index,   TreeNode *nodeinfo)
{
	if (NULL != tree)
	{
		if (tree->index == index)
		{
			nodeinfo = tree;
			return;
		}
		mytree_preorder_get_node(tree->FirstChild, index, nodeinfo);
		mytree_preorder_get_node(tree->NextSibing, index, nodeinfo);
	}
	
	return ;
}

/*
*	功能:通過結點的index獲取結點的指標資訊
*	入參:查詢結點的index
*	返回值:成功返回指向結點的指標,不成功返回NULL
*/
TreeNode *mytree_get_node_by_index(const int index)
{
	TreeNode *tmpNode = NULL;
	TreeNode *root = NULL;
		
	if(true != mytree_check_node_index(index)) 
	{
		printf("invalied index\n");
		return NULL;
	}

	root = g_tree.root;

	//遍歷當前的樹,返回指定結點的指標
	mytree_preorder_get_node(root, index, tmpNode);

	return tmpNode;
}


/*
*	功能:設定一個孩子到樹中
*	入參:parentIndex: 父節點的index
	  element :孩子結點的資訊
*	返回值:插入成功返回0, 失敗返回-1
*/
int mytree_set_child(int parentIndex, int index, ElementType element)
{
	TreeNode *parentNode = NULL;
	TreeNode *newNode = NULL;
	TreeNode *head = NULL;
	TreeNode *lastChild = NULL;
	
	//檢測父節點是否有效
	if(true != mytree_check_node_index(parentIndex)) 
	{
		printf("invalied parent index\n");
		return ERROR;
	}

	parentNode = mytree_get_node_by_index(parentIndex);
	if (NULL == parentNode)
	{
		return ERROR;
	}

	//lastChild = mytree_get_last_child(parentNode);
	newNode = (TreeNode *)malloc(sizeof(TreeNode));
	if(NULL == newNode)
	{
		return ERROR;
	}
	memset(newNode, 0, sizeof(TreeNode));
	newNode->index = index;
	newNode->element.id = element.id;
	memcpy(newNode->element.name, element.name, MAX_NAME_LEN);

	g_tree.nodeIndexs.push_back(index);
	g_tree.num++;

	if (NULL == parentNode->FirstChild)
	{
		parentNode->FirstChild = newNode;
		return OK;
	}
	
	if(NULL == parentNode->NextSibing)
	{
		parentNode->NextSibing = newNode;
		return OK;
	}

	head = parentNode->NextSibing;
	while(head)
	{
		lastChild = head;
		head = head->NextSibing;
	}

	lastChild->NextSibing = newNode;

	return OK;
}

/*
*	功能:設定一個樹的根節點
*	入參:  element :根結點的資訊
*	返回值:插入成功返回0, 失敗返回-1
*/
int mytree_set_root( ElementType element)
{
	//檢測父節點是否有效
	TreeNode *newNode = NULL;

	newNode = (TreeNode *)malloc(sizeof(TreeNode));
	if (NULL == newNode)
	{
		return ERROR; 
	}
	memset(newNode, 0, sizeof(TreeNode));

	newNode->index = 0;//根節點index
	newNode->FirstChild = NULL;
	newNode->NextSibing = NULL;
	newNode->element.id = element.id;
	memcpy(newNode->element.name, element.name, MAX_NAME_LEN);

	g_tree.nodeIndexs.push_back(0);
	g_tree.num++;
	g_tree.root = newNode;
	
	return OK;
}


/*
*	功能:初始化當前樹
*	入參:無
*	返回值:無
*/
void mytree_init()
{
	g_tree.num = 0;
	g_tree.rootIndex = 0;
	g_tree.root = NULL;

	return;
}


/*
*    功能:獲取指定的結點指標
*	 入參:父節點,比較引數index,出參nodeinfo
*	 返回值:NA
*/
void mytree_preorder_visit(TreeNode *tree)
{
	if (NULL != tree)
	{
		printf("tree index :%d\n", tree->index);
		printf("tree element id :%d\n", tree->element.id);
		printf("tree element id :%s\n", tree->element.name);
		mytree_preorder_get_node(tree->FirstChild);
		mytree_preorder_get_node(tree->NextSibing);
	}
	
	return ;
}


/*
*    功能:列印整個樹的結點
*	 入參:父節點,比較引數index,出參nodeinfo
*	 返回值:NA
*/
void mytree_dump()
{
	// 各種遍歷方式去訪問樹的各個結點
	mytree_preorder_visit(g_tree.root)
	return ;
}


/*
*	功能:建立一棵樹
*	入參:無
*	返回值:無
*/

void mytree_create()
{
	ElementType element;

	memset(&element, 0, sizeof(ElementType));
	//初始化一棵樹
    mytree_init();
	//設定樹的根節點
	element.id = 0;
	strcncpy(element.name, "root", sizeof(element.name)-1);
	mytree_set_root(element);

	//設定葉子結點
	memset(&element, 0, sizeof(ElementType));
	element.id = 1;
	strcncpy(element.name, "root-child-1", sizeof(element.name)-1);
	mytree_set_child(0, 1, element);

	memset(&element, 0, sizeof(ElementType));
	element.id = 2;
	strcncpy(element.name, "root-child-2", sizeof(element.name)-1);
	mytree_set_child(0, 2, element);

	memset(&element, 0, sizeof(ElementType));
	element.id = 3;
	strcncpy(element.name, "root-child-3", sizeof(element.name)-1);
	mytree_set_child(0, 3, element);

	memset(&element, 0, sizeof(ElementType));
	element.id = 4;
	strcncpy(element.name, "root-child-1-1", sizeof(element.name)-1);
	mytree_set_child(1, 4, element);

	memset(&element, 0, sizeof(ElementType));
	element.id = 5;
	strcncpy(element.name, "root-child-1-2", sizeof(element.name)-1);
	mytree_set_child(1, 5, element);

	return ;
}

/*
*	功能:測試當前樹結構
*	入參:無
*	返回值:無
*/

void tree_test()
{
    //建立一棵樹
	mytree_create();

	//列印樹的結點
	mytree_dump();
	return ;
}


相關推薦

資料結構與演算法C語言 | 二叉排序

二叉排序樹的定義—— 二叉排序樹 ( Binary Sort Tree) 或者為空;或者是具有如下特性的二叉樹: (1)若根的左子樹不空,則左子樹上所有結點的關鍵字均小於根結點的關鍵字; (2)若

資料結構-順序佇列C語言

佇列:插入資料只在隊尾進行,刪除資料只在隊頭進行。 順序佇列操作會出現 假溢位(tail指向佇列最後,進行入隊操作時,即使前面有空位置也顯示佇列已滿) 解決: 1.在出隊操作後,增加移動元素操作。每次進行完出隊操作後,佇列中後面的元素向前移動,始終保持佇列第一個位置有元素。

資料結構與演算法C語言 | 線性表順序儲存、鏈式儲存

   線性表是最常用最簡單的線性結構    線性結構具有以下基本特徵: 線性結構是一個數據元素的有序(次序)集(處理元素有限)。若該集合非空,則 1)必存在唯一的一個“第一元素”; 2)必存在唯一的一個“最後元素”; 3)除第一元素之外,其餘每個元素均有唯一的前

二叉排序實現C語言

#include <stdio.h> #include <stdlib.h> // 定義基本的資料結構和型別預定義 struct TreeNode; typedef struct TreeNode *Position; typedef

資料結構實現C語言

1、樹的概念    樹形結構是節點之間以及分支關係定義的層次結構。作為一種重要的非線性結構,樹形結構中一個節點最多隻有一個前驅節點,但是可以有多個後繼節點。2、樹的儲存結構    在計算機中,樹有多種的儲存方式,下面介紹一種動態的“左子/右兄”二叉連結串列表示方法。#incl

資料結構實現 5.1:對映_基於實現C++版

資料結構實現 5.1:對映_基於樹實現(C++版) 1. 概念及基本框架 2. 基本操作程式實現 2.1 增加操作 2.2 刪除操作 2.3 修改操作 2.4 查詢操作 2.5 其他操作 3. 演算法複

資料結構實現 10.2:對映_基於AVL實現C++版

資料結構實現 10.2:對映_基於AVL樹實現(C++版) 1. 概念及基本框架 2. 基本操作程式實現 2.1 增加操作 2.2 刪除操作 2.3 修改操作 2.4 查詢操作 2.5 其他操作 3.

資料結構實現 4.1:集合_基於二分搜尋實現C++版

資料結構實現 4.1:集合_基於二分搜尋樹實現(C++版) 1. 概念及基本框架 2. 基本操作程式實現 2.1 增加操作 2.2 刪除操作 2.3 查詢操作 2.4 其他操作 3. 演算法複雜度分析

資料結構】順序佇列的實現C語言

佇列的基本概念及其描述 佇列是一種特殊的線性表,它的特殊性在於佇列的插入和刪除操作分別在表的兩端進行。 插入的那一端稱為隊尾,刪除的那一端稱為隊首。佇列的插入操作和刪除操作分別稱為進隊和出隊。 先進先出(First In First Out) 順序佇列要掌握以下操作:

Linux學習筆記演算法與資料結構之 二叉搜尋程式碼C語言

1、程式碼在VS2010的C++編譯器中編譯通過,可能有極少部分語法不符合C99標準;bool型別無法使用,用int代替 2、由於VS配置問題,沒有分.c和.h檔案書寫;如果要分,最好將Create_Node和Destory_Node加上static關鍵字修飾,他們只會在所

資料結構】鏈式棧的實現C語言

棧的鏈式儲存稱為鏈式棧,鏈式棧是一種特殊的單鏈表,它的插入和刪除規定在單鏈表的同一端進行。鏈式棧的棧頂指標一般用top表示。(個人理解:相當於只對單鏈表的第一個結點進行操作) 鏈式棧要掌握以下基本操作: 1、建立一個空鏈式棧 2、判斷鏈式棧是否為空 3、讀鏈式棧的

二叉的鏈式儲存結構實現C語言完整程式碼+詳細註釋

鏈式儲存結構儲存二叉樹,實際上就是採用連結串列儲存二叉樹。 既然是使用連結串列,首先需要構建連結串列中節點的結構。考慮到儲存物件為二叉樹,其各個節點最多包含 3 部分,依次是:左孩子、節點資料和右孩子,因此,連結串列的每個節點都由這 3 部分組成: 圖 1 二叉連結串列結點構成 圖 1 中,Lchi

資料結構之串的基本操作的實現c語言

我們先一起來看串的一些概念… 字串(簡稱串),可以將其看作是種特殊的線性表,其特殊性在於線性表的資料元素的型別總是字元性,字串的資料物件約束為字符集。 串是由0個或多個字元組成的有限序列。一般記作:s = “s1 s2 s3 …. sn”,,其中,s是串名

資料結構】順序棧的實現C語言

棧的基本概念及其描述 棧是一種特殊的線性表,規定它的插入運算和刪除運算均線上性表的同一端進行,進行插入操作和刪除操作的那一端稱為棧頂,另一端稱為棧底。 棧的插入操作和刪除操作分別稱為進棧和出棧。 FILO(First In Last Out)後進先出/先進後出 eg

資料結構之陣列C語言實現

陣列是大家很熟悉的一種資料型別,而且在我們的程式設計中也應用非常廣泛。這裡以抽象資料型別的形式討論陣列的定義和實現。 一、陣列的定義 假設n維陣列中含有第i維的長度為b(i),則陣列的總長度為b(0) *b(1)*...*b(n-1),每個元素都受著n個

資料結構——線性表的順序表示和實現c語言

PS:資料結構(C語言版)——清華大學出版社, 2.1節程式碼實現#include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define E

二叉查詢的查詢、插入、刪除、釋放等基本操作的實現C語言

二叉查詢樹是一種特殊性質的二叉樹,該樹中的任何一個節點,它的左子樹(若存在)的元素值小於節點的元素值,右子樹(若存在)的元素值大於節點的元素值。 實現了二叉樹查詢樹的實現以及基本操作,包括查詢、插入、刪除、初始化、釋放等。 原始碼下載地址:http://download.c

線索二叉實現C語言

概念 鑑於普通二叉樹使用過程中會出現空間的浪費,後人對在在二叉樹的的基礎上做了改進,利用它的空指標域存放在某種遍歷次序下指向它的前驅結點,和後繼結點的指標。這些指標稱為線索,相應的二叉樹就成了線索二叉樹。 結點結構 Ltag為0時指向該結點的左孩子,

資料結構題集C語言》電子書下載 -百度網盤 高清版PDF格式

     作者:嚴蔚敏,吳偉民,米寧 出版日期:1999-2-1 出版社:清華出版社 頁數:234 ISBN:9787302033141 檔案格式:PDF 檔案大小:18.13 MB     本

二叉插入和刪除操作的遞迴實現c語言

連結串列和陣列是最常見的資料結構,對於資料結構來說,查詢(Find),最大最小值(FindMin,FindMax),插入(Insert)和刪除(Delete)操作是最基本的操作。對於連結串列和陣列來說,這些操作的時間界為O(N),其中N為元素的個數。陣列的插入和刪除需要對其他