? ? ? 在用二叉樹實現散列表之前,首先需要明白的是二叉樹與散列表各自的特性。
? ? ? ?對于二叉樹,主要表現形式是一對二;拿鏈型二叉樹來說,即一個結點含有一個前驅,兩個后繼,兩個后繼即是該結點的兩個孩子,如圖。建立和處理用遞歸的方法可以輕松實現。具體關于樹的結構在此不再詳解。
? ? ? ?對于散列表,通俗來說,即對于將要插入的元素再通過一種函數式(如取余)后,得到一個具體數字(或字符),這個數字(或字符)將決定該元素所存放的位置,如果這個位置已經存有元素,則需要再次經過一系列的處理(或計算)得到一個新的地址位置,然后再原來的元素存入該為空的位置;具體的實現方法在此也不再詳解。
? ? ? ?在對兩者進行結合的過程中,需要考慮兩者的特性,然后再進行實現。下面是個人在VC環境下使用了兩個自定義函數對其進行中序實現的過程。
? ? ? 數字可以分為兩種,奇數和偶數,根據此特點,可以對該數字進行不斷的除二取余的方式得到儲存地址
? ? ? 如圖,首先插入的數是2,2%2==0,則在頭結點的左邊建立一個結點,存放數字2,并將其地址賦予頭結點的lchild,然后插入的是奇數3,判斷得其為奇數,故存放與右側地址2;在再次插入偶數6時,經判斷,6是偶數,而地址1中又存有元素,則需要重新尋找新的空的地址,再次做出的處理是6/2=3;3是奇數,則存放的是4,即作為1的右子樹,依次類推,在相應的地址已經存放有元素的情況下,改變參數,尋找新的地址。由于每個數在取余過一定的次數以后,得到的數是不會重復的,所以每一個數字都會有一個地址來存放,不會發生沖突,二叉樹就可以順利實現。
? ? ? 在其中需要注意的是,每個元素在經過除二之后雖然參數發生了變化,但是在找到并開辟好了需要存放該元素的空間后,存放的元素卻還是客戶端鍵入的原數字,所以在程序的運行中,要注意賦值對象是否正確。所以我在程序的實現中,采用了函數嵌套的方法,一個函數的作用是找到地址開辟空間,其返回值便是需要進行賦值的空間,在調用過后,只需將原來的元素放到該返回地址的相應區域即可。
? ? ? ?如果各位還不夠明白,則下面開始解讀程序。
? ? ? ?在運行開始,用戶首先鍵入數字2,初始化成功的情況下,判斷出2的存放位置應是位置1,(滿足條件2%2==0&&p->lchild==NULL)這時建立一個結點,把這個結點放到頭結點的左子樹處,返回這個新建結點的地址,find函數執行一次,由于判斷語句是else if型,直接退出進入insert函數實現賦值。在插入12時,滿足else if (data%2==0&&p->lchild !=NULL),進入遞歸,p指向的是地址1,12/2==6,參數為6,對6繼續判斷,滿足else if (data%2==0&&p->lchild!=NULL),再次遞歸,直到else if (data%2==1&&p->rchild==NULL),此時,data為3,開始創建空間并且退出遞歸,最后,在insert中返回的地址仍為新開辟的地址,此時開始賦值。
? ? ? ?在進行刪除的過程中,只需要找到對應與欲刪除元素相匹配的地址,然后改變地址中元素的值即可(如if (p->data==data)p->data=-1;)遍歷時遇到-1即不進行遍歷即可,不需要釋放空間。
以上存屬個人看法,如有不足,歡迎指正。