? ? ? 在用二叉樹實現(xiàn)散列表之前,首先需要明白的是二叉樹與散列表各自的特性。
? ? ? ?對于二叉樹,主要表現(xiàn)形式是一對二;拿鏈型二叉樹來說,即一個結(jié)點含有一個前驅(qū),兩個后繼,兩個后繼即是該結(jié)點的兩個孩子,如圖。建立和處理用遞歸的方法可以輕松實現(xiàn)。具體關(guān)于樹的結(jié)構(gòu)在此不再詳解。

? ? ? ?對于散列表,通俗來說,即對于將要插入的元素再通過一種函數(shù)式(如取余)后,得到一個具體數(shù)字(或字符),這個數(shù)字(或字符)將決定該元素所存放的位置,如果這個位置已經(jīng)存有元素,則需要再次經(jīng)過一系列的處理(或計算)得到一個新的地址位置,然后再原來的元素存入該為空的位置;具體的實現(xiàn)方法在此也不再詳解。
? ? ? ?在對兩者進(jìn)行結(jié)合的過程中,需要考慮兩者的特性,然后再進(jìn)行實現(xiàn)。下面是個人在VC環(huán)境下使用了兩個自定義函數(shù)對其進(jìn)行中序?qū)崿F(xiàn)的過程。

? ? ? 數(shù)字可以分為兩種,奇數(shù)和偶數(shù),根據(jù)此特點,可以對該數(shù)字進(jìn)行不斷的除二取余的方式得到儲存地址

? ? ? 如圖,首先插入的數(shù)是2,2%2==0,則在頭結(jié)點的左邊建立一個結(jié)點,存放數(shù)字2,并將其地址賦予頭結(jié)點的lchild,然后插入的是奇數(shù)3,判斷得其為奇數(shù),故存放與右側(cè)地址2;在再次插入偶數(shù)6時,經(jīng)判斷,6是偶數(shù),而地址1中又存有元素,則需要重新尋找新的空的地址,再次做出的處理是6/2=3;3是奇數(shù),則存放的是4,即作為1的右子樹,依次類推,在相應(yīng)的地址已經(jīng)存放有元素的情況下,改變參數(shù),尋找新的地址。由于每個數(shù)在取余過一定的次數(shù)以后,得到的數(shù)是不會重復(fù)的,所以每一個數(shù)字都會有一個地址來存放,不會發(fā)生沖突,二叉樹就可以順利實現(xiàn)。
? ? ? 在其中需要注意的是,每個元素在經(jīng)過除二之后雖然參數(shù)發(fā)生了變化,但是在找到并開辟好了需要存放該元素的空間后,存放的元素卻還是客戶端鍵入的原數(shù)字,所以在程序的運行中,要注意賦值對象是否正確。所以我在程序的實現(xiàn)中,采用了函數(shù)嵌套的方法,一個函數(shù)的作用是找到地址開辟空間,其返回值便是需要進(jìn)行賦值的空間,在調(diào)用過后,只需將原來的元素放到該返回地址的相應(yīng)區(qū)域即可。
? ? ? ?如果各位還不夠明白,則下面開始解讀程序。
? ? ? ?在運行開始,用戶首先鍵入數(shù)字2,初始化成功的情況下,判斷出2的存放位置應(yīng)是位置1,(滿足條件2%2==0&&p->lchild==NULL)這時建立一個結(jié)點,把這個結(jié)點放到頭結(jié)點的左子樹處,返回這個新建結(jié)點的地址,find函數(shù)執(zhí)行一次,由于判斷語句是else if型,直接退出進(jìn)入insert函數(shù)實現(xiàn)賦值。在插入12時,滿足else if (data%2==0&&p->lchild !=NULL),進(jìn)入遞歸,p指向的是地址1,12/2==6,參數(shù)為6,對6繼續(xù)判斷,滿足else if (data%2==0&&p->lchild!=NULL),再次遞歸,直到else if (data%2==1&&p->rchild==NULL),此時,data為3,開始創(chuàng)建空間并且退出遞歸,最后,在insert中返回的地址仍為新開辟的地址,此時開始賦值。
? ? ? ?在進(jìn)行刪除的過程中,只需要找到對應(yīng)與欲刪除元素相匹配的地址,然后改變地址中元素的值即可(如if (p->data==data)p->data=-1;)遍歷時遇到-1即不進(jìn)行遍歷即可,不需要釋放空間。
以上存屬個人看法,如有不足,歡迎指正。