二叉排序樹的構造,插入,刪除,完整c程式碼實現
阿新 • • 發佈:2018-12-09
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode{
int data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
//在給定的BST中插入結點,其資料域為element
void BSTInsert( BiTree *t, int element )
{
if( NULL == *t ) {
(*t) = (BiTree)malloc(sizeof(BiTNode));
(*t)->data = element;
(*t)->lchild = (*t)->rchild = NULL;
}
if( element == (*t)->data )
return ;
else if( element < (*t)->data )
BSTInsert( &(*t)->lchild, element );
else
BSTInsert( &(*t)->rchild, element );
}
//建立BST
void CreateBST( BiTree *t, int *a, int n )
{
(*t) = NULL;
for( int i=0; i<n; i++ )
BSTInsert( t, a[i] );
}
//BST的遞迴查詢
void SearchBST( BiTree t, int key )
{
BiTree p;
p = t;
if( p ) {
if( key == p->data )
printf("查詢成功!\n");
else if( (key < p->data) && (NULL != p->lchild) )
SearchBST( p->lchild , key );
else if( (key > p->data) && (NULL != p->rchild) )
SearchBST( p->rchild , key );
else
printf("無此元素!\n");
}
}
//BST結點的刪除
void DelBSTNode( BiTree t, int key )
{
BiTree p, q;
p = t;
int temp;
while( NULL != p && key != p->data ) {
q = p;
if( key < p->data )
p = p->lchild ;
else
p = p->rchild ;
}
if( NULL == p )
printf("無此元素!\n");
else {
//情況1:結點p的雙親結點為q,且p為葉子結點,則直接將其刪除。
if( NULL == p->lchild && NULL == p->rchild ) {
if( p == q->lchild )
q->lchild = NULL;
if( p == q->rchild )
q->rchild = NULL;
free(p);
p = NULL;
}
//情況2:結點p的雙親結點為q,且p只有左子樹或只有右子樹,則可將p的左子樹或右子樹直接改為其雙親結點q的左子樹或右子樹。
else if( (NULL == p->rchild && NULL != p->lchild) ) { //p只有左子樹
if( p == q->lchild )
q->lchild = p->lchild ;
else if( p == q->rchild )
q->rchild = p->lchild ;
free(p);
p = NULL;
}
else if( NULL == p->lchild && NULL != p->rchild ) { //p只有右子樹
if( p == q->lchild )
q->lchild = p->rchild ;
if( p == q->rchild )
q->rchild = p->rchild ;
free(p);
p = NULL;
}
//情況3:結點p的雙親結點為q,且p既有左子樹又有右子樹。本程式碼使用直接前驅(也可以直接後繼)
else if( NULL != p->lchild && NULL != p->rchild ) {
BiTree s, sParent;
sParent = p;
s = sParent->lchild ;
while( NULL != s->rchild ) { //找到p的直接前驅
sParent = s;
s = s->rchild ;
}
temp = s->data ;
DelBSTNode( t, temp );
p->data = temp;
}
}
}
//中序遍歷列印BST
void PrintBST( BiTree t )
{
if( t ) {
PrintBST( t->lchild);
printf("%d ", t->data);
PrintBST( t->rchild);
}
}
int main()
{
int n;
int *a;
int key;
BiTree t;
printf("請輸入二叉查詢樹的結點數:\n");
scanf("%d", &n);
a = (int *)malloc(sizeof(int)*n);
printf("請輸入二叉找樹的結點資料:\n");
for( int i=0; i<n; i++ )
scanf("%d", &a[i]);
CreateBST( &t, a, n );
printf("當前二叉查詢樹的遍歷為:\n");
PrintBST( t );
printf("\n");
printf("請輸入要查詢的元素:\n");
scanf("%d", &key);
printf("查詢結果:\n");
SearchBST( t, key ); //遞迴查詢
printf("\n");
printf("請輸入要刪除的元素:\n");
scanf("%d", &key);
DelBSTNode( t, key );
printf("當前二叉查詢樹的遍歷為:\n");
PrintBST( t);
printf("\n");
return 0;
#include <stdlib.h>
typedef struct BiTNode{
int data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
//在給定的BST中插入結點,其資料域為element
void BSTInsert( BiTree *t, int element )
{
if( NULL == *t ) {
(*t) = (BiTree)malloc(sizeof(BiTNode));
(*t)->data = element;
(*t)->lchild = (*t)->rchild = NULL;
}
if( element == (*t)->data )
return ;
else if( element < (*t)->data )
BSTInsert( &(*t)->lchild, element );
else
BSTInsert( &(*t)->rchild, element );
}
//建立BST
void CreateBST( BiTree *t, int *a, int n )
{
(*t) = NULL;
for( int i=0; i<n; i++ )
BSTInsert( t, a[i] );
}
//BST的遞迴查詢
void SearchBST( BiTree t, int key )
{
BiTree p;
p = t;
if( p ) {
if( key == p->data )
printf("查詢成功!\n");
else if( (key < p->data) && (NULL != p->lchild) )
SearchBST( p->lchild , key );
else if( (key > p->data) && (NULL != p->rchild) )
SearchBST( p->rchild , key );
else
printf("無此元素!\n");
}
}
//BST結點的刪除
void DelBSTNode( BiTree t, int key )
{
BiTree p, q;
p = t;
int temp;
while( NULL != p && key != p->data ) {
q = p;
if( key < p->data )
p = p->lchild ;
else
p = p->rchild ;
}
if( NULL == p )
printf("無此元素!\n");
else {
//情況1:結點p的雙親結點為q,且p為葉子結點,則直接將其刪除。
if( NULL == p->lchild && NULL == p->rchild ) {
if( p == q->lchild )
q->lchild = NULL;
if( p == q->rchild )
q->rchild = NULL;
free(p);
p = NULL;
}
//情況2:結點p的雙親結點為q,且p只有左子樹或只有右子樹,則可將p的左子樹或右子樹直接改為其雙親結點q的左子樹或右子樹。
else if( (NULL == p->rchild && NULL != p->lchild) ) { //p只有左子樹
if( p == q->lchild )
q->lchild = p->lchild ;
else if( p == q->rchild )
q->rchild = p->lchild ;
free(p);
p = NULL;
}
else if( NULL == p->lchild && NULL != p->rchild ) { //p只有右子樹
if( p == q->lchild )
q->lchild = p->rchild ;
if( p == q->rchild )
q->rchild = p->rchild ;
free(p);
p = NULL;
}
//情況3:結點p的雙親結點為q,且p既有左子樹又有右子樹。本程式碼使用直接前驅(也可以直接後繼)
else if( NULL != p->lchild && NULL != p->rchild ) {
BiTree s, sParent;
sParent = p;
s = sParent->lchild ;
while( NULL != s->rchild ) { //找到p的直接前驅
sParent = s;
s = s->rchild ;
}
temp = s->data ;
DelBSTNode( t, temp );
p->data = temp;
}
}
}
//中序遍歷列印BST
void PrintBST( BiTree t )
{
if( t ) {
PrintBST( t->lchild);
printf("%d ", t->data);
PrintBST( t->rchild);
}
}
int main()
{
int n;
int *a;
int key;
BiTree t;
printf("請輸入二叉查詢樹的結點數:\n");
scanf("%d", &n);
a = (int *)malloc(sizeof(int)*n);
printf("請輸入二叉找樹的結點資料:\n");
for( int i=0; i<n; i++ )
scanf("%d", &a[i]);
CreateBST( &t, a, n );
printf("當前二叉查詢樹的遍歷為:\n");
PrintBST( t );
printf("\n");
printf("請輸入要查詢的元素:\n");
scanf("%d", &key);
printf("查詢結果:\n");
SearchBST( t, key ); //遞迴查詢
printf("\n");
printf("請輸入要刪除的元素:\n");
scanf("%d", &key);
DelBSTNode( t, key );
printf("當前二叉查詢樹的遍歷為:\n");
PrintBST( t);
printf("\n");
return 0;
}
程式碼已實現!