1. 程式人生 > >資料結構學習——帶父節點的二叉搜尋樹全部功能c++實現

資料結構學習——帶父節點的二叉搜尋樹全部功能c++實現

第二篇二叉樹我們帶來純c++版本的二叉搜尋樹,這篇程式碼是我學習了很多優秀程式碼之後寫出來的,大家在學習二叉搜尋樹的同時可以著重看下在這裡如何定義的二叉搜尋樹,以及Private和Public的封裝聯動,對程式碼思路是一個很好的提升。

注:在這裡的遍歷我只寫了前序遍歷,其他的遍歷方式大家可以看我的前一篇部落格,一共寫到了兩個大方法共計5種小方法的遍歷~~

猛男話不多,程式碼走起

#include<iostream>

using namespace std;

typedef int data_type;

class BinaryNode{
	
	private:
		BinaryNode *rchild;
		BinaryNode *lchild;
		BinaryNode *parent;
		data_type key;
		friend class BinarySTree;
			
		public:
		BinaryNode(BinaryNode *r = NULL,BinaryNode *l = NULL,BinaryNode *p = NULL,data_type a = 0):rchild(r),lchild(l),parent(p),key(a){}		
};

class BinarySTree{
	
	private:
		BinaryNode *root;
		
		//變換節點 用change替換old 
		void change(BinaryNode *&tmp,BinaryNode *old,BinaryNode *change) 
		{
			if(!old->parent)
			{
				tmp = change;
			}
			else if(old = old->parent->rchild)
				old->parent->rchild = change;
			else
				old->parent->lchild = change;
			if(change)
				change->parent = old->parent;
		}
		
		//先序遍歷BST 
		void search(BinaryNode *p)
		{
			if(p)
			{
				cout<<p->key<<" ";
				search(p->lchild);
				search(p->rchild);
			}
		}
		
		
		//找子樹最大值 
		BinaryNode *Max(BinaryNode *p)
		{
			while(p->rchild)
			{
				p = p->rchild;
			}
			return p;
		}
		
		//找子樹最小值
		BinaryNode *Min(BinaryNode *p)
		{
			while(p->lchild)
			{
				p = p->lchild;	
			}	
			return p;
		}
		 
		//找已知節點的前驅結點 
		BinaryNode *ForwardNode(BinaryNode *p)
		{
			BinaryNode *old;
			if(p->lchild)
			{
				return Max(p->lchild);
			}
			else
			{
				old = p->parent;
				while(old && old->rchild!=p)
				{
					p = old;
					old = old->parent;
				}
			}
			return old;
		}
		
		//找已知的後繼節點 
		BinaryNode *BackwardNode(BinaryNode *p)
		{
			BinaryNode *old;
			if(p->rchild)
			{
				return Min(p->rchild);
			}
			else
			{
				old = p->parent;
				while(old && old->lchild!=p)
				{
					p = old;
					old = old->parent;
				}
			}
			return old;
		}
		
		//插入新的節點 
		void TInsert(BinaryNode *&tmp, BinaryNode *z)
		{
			BinaryNode *p = tmp;
			BinaryNode *temp = NULL;
			
			while(p)
			{
				temp = p;
				if(z->key < p->key)
					p = p->lchild;
				else
					p = p->rchild;
			}
			
			z->parent = temp;
			
			if(!temp)
				tmp = z;
			
			else if(z->key < temp->key)
				temp->lchild = z;
			
			else
				temp->rchild = z;	
		}
		
		//新增固定key值的節點 
		
		void add(BinaryNode *&tmp, data_type key)
		{
			
			BinaryNode *temp = tmp;
			BinaryNode *z = NULL;
			BinaryNode *a = new BinaryNode(NULL,NULL,NULL,key);
			
			while(temp)
			{
				z = temp;
				
				if(key > temp->key)
				{
					temp = temp->rchild;		
				}
				else if(key < temp->key)
				{
					temp = temp->lchild;
				}
			}
			
			if(a->key > z->key)
				{
					z->rchild = a;
					a->parent = z;
				}
			else if(a->key < z->key)
				{
					z->lchild = a;
					a->parent = z;
				}

			
			cout<<"插入結束新的BST為: ";
			search(tmp);
		}
		
		//刪除固定key的節點 
		
		void deleteNode(BinaryNode *&tmp,data_type key)
		{
			BinaryNode *p = tmp;
			BinaryNode *p1 = NULL;
		
			
			while(p&&p->key!=key)
			{
				if(key > p->key)
				{
					p = p->rchild;
				}
				else if(key < p->key)
				{
					p = p->lchild;
				}
			}
						
			//如果被刪除節點的 度 == 0
			
			 if(!p->lchild&&!p->rchild)
			{
				if(p == p->parent->rchild)
					p->parent->rchild = NULL;
				else if(p == p->parent->lchild)
					p->parent->lchild = NULL;
			} 
			
			
			//如果被刪除節點的 度 == 1 
			
			else if(!p->lchild||!p->rchild)
			{
				if(p->lchild)
				{
					if(p == p->parent->lchild)
					
						p->parent->lchild = p->lchild;
					
					else if(p == p->parent->rchild)
					
						p->parent->rchild = p->lchild; 
				}
				else if(p->rchild)
				{
					if(p == p->parent->lchild)
					
						p->parent->lchild = p->rchild;
					
					else if(p == p->parent->rchild)
					
						p->parent->rchild = p->rchild; 
				}
			}

			
			//如果被刪除節點的 度 == 2 
			
			else 
			{
				BinaryNode *a = Min(p->rchild);
				
				if(p->rchild == a)
				{
					change(root,p,p->rchild);
					p->rchild->lchild = p->lchild;
					p->rchild->lchild->parent = p->rchild;
				}
				else
				{
					change(root,a,a->rchild);
					a->rchild->lchild = p->rchild;
					a->rchild->lchild->parent = a->rchild;
					
					change(root,p,a);
					a->lchild = p->lchild;
					p->lchild->parent = a;
				}
			}
		
		}
		
	
		
	public:
		
		BinarySTree():root(NULL){}
		
                //下面是main函式訪問到的公用介面的定義

		void Search()
		{
			search(root);
			cout<<endl;
		}
		
		void Insert(data_type key)
		{
			BinaryNode *p = new BinaryNode(NULL,NULL,NULL,key);
			TInsert(root,p); 
		}
		
		void *Forward(BinaryNode *p)
		{
			ForwardNode(p);
		}
		
		void *Backward(BinaryNode *p)
		{
			BackwardNode(p);
		}
		
		BinaryNode *findMax(BinaryNode *p)
		{
			return Max(p);
		}
		
		BinaryNode *findMin(BinaryNode *p)
		{
			return Min(p);
		}
		
		void Add(data_type key)
		{
			add(root,key);
		}
		
		void DeleteNode(data_type key)
		{
			deleteNode(root,key);
			search(root);	
		} 
};

int main()
{
	int count = 0;
	cout<<"Input the number of Node: ";
	cin>>count;
	
	int a[count] = {0};
	BinarySTree s1;
	cout<<"Input the Node one by one: ";
	
	for(int i = 0;i < count;i++)
	{
		cin>>a[i];
		s1.Insert(a[i]);
	}
	
	cout<<endl<<"Finish the input"<<endl;
	
	cout<<"該二叉搜尋樹的前序遍歷為:";
	s1.Search();
	
	int temp = 0;
	cout<<endl<<"請輸入需要新增的節點key值: ";
	cin>>temp;
	s1.Add(temp);
	
	int del = 0;
	cout<<endl<<"請輸入需要刪除的節點key值:";
	while(cin>>del)
	{
		s1.DeleteNode(del);
		cout<<endl<<"請輸入需要刪除的節點key值:";
	} 
	system("pause");
}