发新话题
打印

树,二叉树,森林等讨论专区

树,二叉树,森林等讨论专区

我开头:
如何判断二叉树?

先要对二叉树进行层次遍历,在遍历过程中对每一个结点进行检查:
(1)如果当前结点没有右子树,则剩下的全部结点必须既没有左子树,又没有右子树;
(2)如果当前结点有右子树,则它必须也有左子树.

如果同时满足(1)(2),则是完全二叉树;否则不是.




[此贴子已经被作者于2003-7-26 17:31:00编辑过]


TOP

记得我考研那年考了哈夫曼二叉树 下面我把最近收集到的哈夫曼二叉树源码贡献出来: 给定一个字符串,根据统计字符串中各个字符出现的频率对字符进行哈夫曼编码,然后对原字符串进行编码,并输出编码后的内容 ——数据结构 #include #define MAX_NODE 1024 #define MAX_WEIGHT 4096 typedef struct HaffmanTreeNode { char ch, code[15]; int weight; int parent, lchild, rchild; } HTNode, *HaTree; typedef struct { HTNode arr[MAX_NODE]; int total; } HTree; /* 统计字符出现的频率 */ int statistic_char(char *text, HTree *t){ int i, j; int text_len = strlen(text); t->total = 0; for (i=0; itotal; j++) if (t->arr[j].ch == text){ t->arr[j].weight ++; break; } if (j==t->total) { t->arr[t->total].ch = text; t->arr[t->total].weight = 1; t->total ++; } } printf("char frequence\n"); for (i=0; itotal; i++) printf("'%c' %d\n", t->arr.ch, t->arr.weight); printf("\n"); return t->total; } int create_htree(HTree *t) { int i; int total_node = t->total * 2 - 1; int min1, min2; /* 权最小的两个结点 */ int min1_i, min2_i; /* 权最小结点对应的编号 */ int leaves = t->total; for (i=0; iarr.parent = -1; t->arr.rchild = -1; t->arr.lchild = -1; } while (t->total < total_node) { min1 = min2 = MAX_WEIGHT; for (i=0; itotal; i++) { /* 对每一个结点 */ if (t->arr.parent == -1 /* 结点没有被合并 */ && t->arr.weight < min2) { /* 结点的权比最小权小 */ if (t->arr.weight < min1) { /* 如果它比最小的结点还小 */ min2_i = min1_i; min2 = min1; min1_i = i; min1 = t->arr.weight; } else { min2_i = i; min2 = t->arr.weight; } } } t->arr[t->total].weight = min1 + min2; t->arr[t->total].parent = -1; t->arr[t->total].lchild = min1_i; t->arr[t->total].rchild = min2_i; t->arr[min1_i].parent = t->total; t->arr[min2_i].parent = t->total; t->arr[t->total].ch = ' '; t->total ++; } return 0; } /* 对哈夫曼树进行编码 */ void coding(HTree *t, int head_i, char *code) { if ( head_i == -1) return; if (t->arr[head_i].lchild == -1 && t->arr[head_i].rchild == -1) { strcpy(t->arr[head_i].code, code); printf("'%c': %s\n", t->arr[head_i].ch, t->arr[head_i].code); } else { int len = strlen(code); strcat(code, "0"); coding(t, t->arr[head_i].lchild, code); code[len] = '1'; coding(t, t->arr[head_i].rchild, code); code[len] = '\0'; } } /* 中序打印树 */ void print_htree_ldr(HTree *t, int head_i, int deep, int* path) { int i; if (head_i == -1) return; path[deep] = 0; print_htree_ldr(t, t->arr[head_i].lchild, deep + 1, path); if (deep) printf(" "); for (i=1; i==path[i-1]?" ":"│ "); int dir = path==path[i-1]; if ( t->arr[head_i].lchild == -1 && t->arr[head_i].rchild == -1) printf("%s── %d '%c'\n", dir? "┌":"└", t->arr[head_i].weight, t->arr[head_i].ch); else if (head_i != t->total-1) printf("%s─%02d┤\n", dir? "┌":"└"", t->arr[head_i].weight); else printf(" %02d┤\n", t->arr[head_i].weight); path[deep] = 1; print_htree_ldr(t, t->arr[head_i].rchild, deep + 1, path); } /* 对字符进行编码 */ void code_string(char *text, HTree *t) { int i, j, text_len = strlen(text); int n = 0; for (i=0; i; for (j=0; jtotal; j++) if (ch == t->arr[j].ch) { printf("%s ", t->arr[j].code); n += strlen(t->arr[j].code); break; } } printf("\n%d chars, Total len = %d\n", text_len, n); } int main(int argc, char* argv[]) { HTree t; char text[128]="ABAAAAEEEAAACCCCAAAACCDEA"; char code[128] = ""; int path[16]={0}; statistic_char(text, &t); create_htree(&t); print_htree_ldr(&t, t.total-1, 0, path); coding(&t, t.total-1, code); code_string(text, &t); return 0; } 输出结果: char frequence 'A' 13 'B' 1 'E' 4 'C' 6 'D' 1 ┌── 6 'C' ┌─12┤ │ │ ┌── 1 'B' │ │ ┌─02┤ │ │ │ └── 1 'D' │ └─06┤ │ └── 4 'E' 25┤ └── 13 'A' 'C': 00 'B': 0100 'D': 0101 'E': 011 'A': 1 1 0100 1 1 1 1 011 011 011 1 1 1 00 00 00 00 1 1 1 1 00 00 0101 011 来源:eion(原作)

TOP

/* 对二叉树进行层次遍历可以使用队列结构. */ #include #include #define TRUE 1 #define FALSE 0 typedef int BOOL; typedef char DATATYPE; typedef struct _node { DATATYPE Data; struct _node *pLeft; struct _node *pRight; } NODE; /*队列*/ typedef struct { BOOL bIsEmpty; int nFront; int nRear; int nSize; NODE **pData; } QUEUE; /*队列初始化。nSize = 数组大小*/ void InitQueue(QUEUE *pQue, int nSize) { pQue->pData = (NODE **)malloc(sizeof(NODE *) * nSize); pQue->nSize = nSize; pQue->nFront = pQue->nRear = 0; pQue->bIsEmpty = TRUE; } /*入队列*/ BOOL InQueue(QUEUE *pQue, NODE *Data) { if (pQue->bIsEmpty || pQue->nRear != pQue->nFront) /*判断队列是否满*/ { pQue->bIsEmpty = FALSE; pQue->pData[pQue->nRear] = Data; pQue->nRear++; if (pQue->nRear == pQue->nSize) pQue->nRear = 0; return TRUE; } else return FALSE; } /*出队列。pDataBfr为容纳数据的变量的指针*/ BOOL OutQueue(QUEUE *pQue, NODE **pDataBfr) { if (pQue->bIsEmpty) return FALSE; else { *pDataBfr = pQue->pData[pQue->nFront]; pQue->nFront++; if (pQue->nFront == pQue->nSize) pQue->nFront = 0; if (pQue->nFront == pQue->nRear) pQue->bIsEmpty = TRUE; return TRUE; } } /*二叉树的层次遍历并判断是否为完全二叉树*/ BOOL LevelTraverse(NODE *pRoot) { BOOL bResult = TRUE; BOOL bComfine = FALSE; NODE *pCurNode; QUEUE Que; if (pRoot == NULL) return TRUE; InitQueue(&Que,1024); /*这里不考虑队列溢出,在应用中应根据实际情况使用合适 的队列*/ InQueue(&Que,pRoot); while (OutQueue(&Que,&pCurNode)) { if (!pCurNode->pLeft && pCurNode->pRight) { bResult = FALSE; break; } if (bComfine && (pCurNode->pLeft || pCurNode->pRight)) { bResult = FALSE; break; } if (pCurNode->pLeft) InQueue(&Que,pCurNode->pLeft); if (pCurNode->pRight) InQueue(&Que,pCurNode->pRight); else bComfine = TRUE; } return bResult; } /*简单的测试环境*/ /* 从键盘缓冲区中读取一个不为空格且不为回车的字符 */ char GetNextChar(void) { char ch; do { ch = getchar(); } while (ch == ' ' || ch == '\n'); return ch; } /*利用前序遍历序列建立二叉树。扩充结点用‘*’代表。前序序列从键盘输入*/ void CreateTree(NODE *Root) { Root->pLeft = Root->pRight = NULL; if (Root->Data != '*') /* 如果不为扩充结点, 要建立左结点和右结点 */ { Root->pLeft = (NODE *)malloc(sizeof(NODE)); Root->pLeft->Data = GetNextChar(); CreateTree(Root->pLeft); Root->pRight = (NODE *)malloc(sizeof(NODE)); Root->pRight->Data = GetNextChar(); CreateTree(Root->pRight); } } /*除去'*'结点*/ void TrimTree(NODE *pRoot) { if (pRoot->pLeft) if (pRoot->pLeft->Data == '*') { free(pRoot->pLeft); pRoot->pLeft = NULL; } else TrimTree(pRoot->pLeft); if (pRoot->pRight) if (pRoot->pRight->Data == '*') { free(pRoot->pRight); pRoot->pRight = NULL; } else TrimTree(pRoot->pRight); } void main() { NODE Root; Root.Data = GetNextChar(); CreateTree(&Root); TrimTree(&Root); printf("%d\n",LevelTraverse(&Root)); }

TOP

为什么没人讨论呢?

TOP

楼主   可能是太深奥了吧

TOP

为大家提供一些实现源码而已
概念性模糊的东西还是可以讨论的嘛

TOP

引用:
以下是引用少校在2003-7-15 16:10:00的发言:
我开头:
如何判断二叉树?

先要对二叉树进行层次遍历,在遍历过程中对每一个结点进行检查:
(1)如果当前结点没有右子树,则剩下的全部结点必须既没有左子树,又没有右子树;
(2)如果当前结点有右子树,则它必须也有左子树.

如果同时满足(1)(2),则是完全二叉树;否则不是.

楼主说的是完全二叉树的判定,这只是二叉树的一种特例。
读万卷书,行万里路。

TOP


对啊
我说得很清楚了
你再仔细看看:
先要对[glow=255,red,2]二叉树[/glow]进行层次遍历
....
如果同时满足(1)(2),则是[glow=255,red,2]完全二叉树[/glow];否则不是.

TOP

至于判断树是否为二叉树 似乎没有讨论的必要吧

TOP

树与森林,含例子程序,吐血奉献



[此贴子已经被作者于2003-7-26 17:33:34编辑过]


附件: 您所在的用户组无法下载或查看附件

TOP

发新话题