歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

二叉排序樹刪除值小於value的結點

同學去阿裡面試的時候,要求寫出代碼:

現在有一棵二叉排序樹,每個節點保存一個int類型的值,刪除值為10以下的節點(樹中可能不含值為10的節點),說一下思路,寫一下算法。

算了原來錯誤的思路就不拿出來誤導大家了,只能說想簡單了,花了幾天空閒的時間思考這個問題,終於把代碼寫出來了,雖然琢磨了一段時間,但是終究還是寫出來了。

二叉樹的常見問題及其解決程序 http://www.linuxidc.com/Linux/2013-04/83661.htm

【遞歸】二叉樹的先序建立及遍歷 http://www.linuxidc.com/Linux/2012-12/75608.htm

在JAVA中實現的二叉樹結構 http://www.linuxidc.com/Linux/2008-12/17690.htm

【非遞歸】二叉樹的建立及遍歷 http://www.linuxidc.com/Linux/2012-12/75607.htm

二叉樹遞歸實現與二重指針 http://www.linuxidc.com/Linux/2013-07/87373.htm

經過測試數據或者自己畫圖,感覺有這麼幾個難點把

1.如果數據是這樣:6,5,7,8,15,就是先開始根結點的值小於10,後來右子樹中=存在大於10的結點,由於需要釋放小於10的結點,就需要重新調整根結點

2.如果數據是這樣:6,5,7,8,15,14,9,8,13,11,10,就是先開始小於10,然後右子樹出現了大於了10,結果峰回路轉左子樹中又有小於10的結點,其實這組數據基本就包含了核心代碼的思想

代碼思想:如果當前結點小於10的話,就循環查找右子樹,直到找到第一個大於10的結點p,然後調整樹結構,接著循環查找p的左子樹,直到找到又出現第一個小於10的結點,然後遞歸查找右子樹和左子樹整個過程,直到沒有大於10的結點為止

代碼如下,其中題目要求為刪除的值為10,當然更通用的是刪除值為val以下的結點(如果結點值等於val,也會被刪除),另外在創建樹的時候由於為了方便測試代碼,所以隨機生成,但是對於有相同值,會自動忽略,也就是樹中的所有結點值都是唯一的:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

struct biTree{
 struct biTree*lchild,*rchild;
 int data;
};

struct biTree* createBST(struct biTree *root,int val){
 if(root==NULL){
  root=(struct biTree*)malloc(sizeof(struct biTree));
  root->data=val;
  root->lchild=root->rchild=NULL;
  return root;
 }
 if(val<root->data) root->lchild=createBST(root->lchild,val);
 else if(val>root->data) root->rchild=createBST(root->rchild,val);
 return root;
}

void inOrder(struct biTree*root){
 if(root==NULL)  return ;
 inOrder(root->lchild);
 printf("%d ",root->data);
 inOrder(root->rchild);
}

int delVal(struct biTree **root,int val){
 if(root==NULL) return 0;
 struct biTree *p=*root,*pre=*root;
 struct biTree *q=(struct biTree*)malloc(sizeof(struct biTree));
 while(1){
  int value=(*root)->data;
  while(p&&p->data<=val){
   pre=p;
   p=p->rchild;
   free(pre);
  }
  if(value<val) *root=p;    //其實只會調整一次根結點
  else q->lchild=p;
  while(p&&p->data>val){
   pre=p;
   p=p->lchild;
  }
  if(p==NULL)  break;
  q=pre;
 }
 return 1;
}

int main(){
 int i;
 while(1){
  int a[30];
  struct biTree *root=NULL;
  unsigned int seed;
  seed = time(0);
  srand(seed);
  for(i=0;i<10;i++){
   a[i]=rand()%100+1;
  }
  for(i=0;i<10;i++){
   printf("%d ",a[i]);
  }
  printf("\n");

  for(i=0;i<9;i++)  root=createBST(root,a[i]);
  inOrder(root);
  printf("\n");

  int val;
  scanf("%d",&val);  //輸入某個值,小於這個值的所有結點都會被刪除
  delVal(&root,val);
  inOrder(root);
  printf("\n\n");
  root=NULL;
 }
 
 return 0;
}

Copyright © Linux教程網 All Rights Reserved