二叉排序树增删改查

今天闲来无事,自己写了遍排序树,不知怎么是,觉得比教材上写的长,总感觉出错了,可现在没书,有机会再校对校对

bst.h

#ifndef _MY_BST_H_
#define _MY_BST_H_

typedef struct node * link;

struct node {
	int item;
	link l;
	link r;
};


/* 构造一个节点 */
link new_node(int item, link l, link r);

/* 添加一个节点 */
link add_node(link root, int item);

/* 查找一个节点 */
link search_node(link root, int item);

/* 打印出一棵树 */
void print_tree(link root, int level);

/* 删除一个节点 */
link remove_node(link root, int item);

#endif

bst.c

#include "bst.h"
#include <stdlib.h>
#include <stdio.h>

/* 构造一个节点 */
link new_node(int item, link l, link r)
{
	link ptr_node = NULL;

	ptr_node = (link)malloc(sizeof(struct node));
	if(NULL == ptr_node)
		return NULL;
	ptr_node->item = item;
	ptr_node->l = l;
	ptr_node->r = r;
	return ptr_node;
}

/* 添加一个节点 */
link add_node(link root, int item)
{
	if(root == NULL)
		return new_node(item, NULL, NULL);
	if(item < root->item)
		root->l = add_node(root->l, item);
	else 
		root->r = add_node(root->r, item);
	return root;
}

/* 查找一个节点 */
link search_node(link root, int item)
{
	if(root == NULL)
		return NULL;
	if(item < root->item)
		return search_node(root->l, item);
	else if(item > root->item)
		return search_node(root->r, item);
	return root;
}

/* 打印出一棵树 */
void print_tree(link root, int level)
{
	int i = 0;
	if(root == NULL)
		return;
	
	for(i = 0; i < level; i++)
		printf(" ");
	printf("|-%d\n", root->item);
	print_tree(root->l, level + 1);
	print_tree(root->r, level + 1);
}

/* 删除一个节点 */
link remove_node(link root, int item)
{
	link r_root = NULL;	
	link l_root = NULL;	
	link l_root_p = NULL;
	if(root == NULL)
		return NULL;

	if(item < root->item)
	{
		root->l = remove_node(root->l, item);
		return root;
	}
	if(item > root->item)
	{
		root->r = remove_node(root->r, item);
		return root;
	}

	if(root->l == NULL && root->r != NULL)
	{
		/* 直接返回右子树 */
		r_root = root->r;
		free(root);
		return r_root;
	}
	else if(root->l != NULL && root->r == NULL)
	{
		/* 直接返回左子树 */
		l_root = root->l;
		free(root);
		return l_root;
	}
	else if( root->l != NULL && root->r != NULL)
	{
		/* 找到左子树的最大值替换当前节点 */
		l_root_p = root;
		l_root = root->l;
		while(l_root->r){
			l_root_p = l_root;
			l_root = l_root->r;
		}
			
		root->item = l_root->item;	

		if(l_root_p == root)
			l_root_p->l = l_root->l;
		else
			l_root_p->r = l_root->l;

	
		free(l_root);
		return root;
	}			
}

test.c

#include "bst.h"
#include <time.h>
#include <stdio.h>


int main(int c, char * v[])
{
	link root = NULL;
	link sub_root = NULL;
	int i = 0;
	int arr[] = {10, 5, 2, 6, 4};

	for(i = 0; i < sizeof(arr) / sizeof(int); i++)	
		root = add_node(root, arr[i]);
	
	print_tree(root, 0);


	sub_root = search_node(root, 0);
	if(NULL != sub_root)
		printf("find %d\n", sub_root->item);
	else
		printf("not find it\n");

	root = remove_node(root, 5);
	print_tree(root, 0);
	printf("\n");
}

二叉树转换为链表

struct linklist to_linklist(link root)
{
	struct linklist lson_list;
	struct linklist rson_list;
	if(root == NULL){
		lson_list.head = lson_list.tail = NULL;
		return lson_list;
	}

	lson_list = to_linklist(root->l);
	rson_list = to_linklist(root->r);

	if((lson_list.head == NULL) && (rson_list.head != NULL))
	{
		root->l = NULL;
		root->r = rson_list.head;
		rson_list.head->l = root;
		rson_list.head = root;
		lson_list = rson_list;
	}	
	else if((lson_list.head != NULL) && (rson_list.head == NULL))
	{
		lson_list.tail->r = root;
		root->l = lson_list.tail;
		root->r = NULL;
		lson_list.tail = root;
	}
	else if((lson_list.head == NULL) && (rson_list.head == NULL))
	{
		root->l = root->r = NULL;
		lson_list.head = lson_list.tail = root;		
	}
	else
	{
		(lson_list.tail)->r = root;
		(rson_list.head)->l = root;
		root->l = lson_list.tail;
		root->r = rson_list.head;
		lson_list.tail = rson_list.tail;
	}
	return lson_list;
}


makefile

CC=gcc
SRC=bst.c app.c
OBJ=$(subst .c,.o, $(SRC))
APP=bst


$(APP):$(OBJ)
	$(CC) $(OBJ) -o $(APP)

$(OBJ):$(SRC)
	$(CC) $(SRC) -c


clean:
	rm $(OBJ) $(APP) -f




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值