[英]Printing B+ tree in C
我已經在C
實現了B+
樹,並希望以樹形式打印其鍵。 我遵循以下算法進行打印,但遇到了一些分割錯誤。
從根開始,首先對其進行排隊。 然后出隊直到隊列變為零。
由於每個節點都包含鍵及其值(指向下一級節點的指針),因此這些值中的每一個在到達特定節點時也會排隊。
以下是對葉子進行排隊,出隊和打印的代碼。 請讓我知道此partcularcode有什么問題。
typedef struct QUEUE{
BPLUS bplusNode;
struct QUEUE * next;
}*ENQUEUE;
以下代碼是對樹的節點進行排隊。(我將實現廣度優先搜索)
void bplus_Enqueue(BPLUS bplusNew){
ENQUEUE bplusTemp;
if (queue == NULL){
queue = (ENQUEUE)malloc(sizeof(ENQUEUE));
queue->bplusNode= bplusNew;
queue->next = NULL;
}
else {
bplusTemp = (ENQUEUE)malloc(sizeof(ENQUEUE));
bplusTemp->bplusNode = bplusNew;
bplusTemp->next = NULL;
while(queue->next != NULL) {
queue = queue->next;
}
queue->next = bplusTemp;
free(bplusTemp);
}
}
以下代碼用於出隊
BPLUS bplus_Dequeue( void ){
BPLUS bplusTemp = queue->bplusNode;
queue = queue->next;
return bplusTemp;
}
以下代碼用於打印樹。
void bplus_PrintBplus(BPLUS root){
int i;
BPLUS tempBplus;
queue = NULL;
bplus_Enqueue(root);
if(queue == NULL){
printf("Sala kaam garena\n");
}
while(queue != NULL){
tempBplus = bplus_Dequeue();
for(i=0;i<tempBplus->numKeys;i++){
printf("%d -----> %d\n",i,tempBplus->keys[i]);
}
if(tempBplus->next != NULL){
for(i=0;i<=tempBplus->numKeys;i++)
bplus_Enqueue(tempBplus->pointers[i]);
}
}
}
此代碼打印root
的鍵值和root
第一個連續節點,然后出現分段錯誤。 您能幫我弄清楚這段代碼有什么問題嗎?
我沒有檢查完整的代碼,但是這些部分確實很奇怪:
bplusTemp->bplusNode = bplusNode;
這里的bplusNode是什么? 還沒有看到它的聲明。
queue->next = bplusTemp;
free(bplusTemp);
這只是簡單的堅果:)
級別順序遍歷是通過兩個隊列完成的,一個隊列用於訪問當前級別的元素,另一個隊列用於為下一個級別建立隊列。 我已經為二進制搜索樹成功實現了這一點。 您可以對B +樹使用相同的邏輯。
void BinarySearchTree::printLevelBased()
{
Queue<Node *> *nodeQueue1 = new Queue<Node *>();
Queue<Node *> *nodeQueue2 = new Queue<Node *>();;
Node *currentNode;
int numOfLevels = 0;
nodeQueue1->put(mRoot);
while(false == nodeQueue1->isEmpty())
{
numOfLevels++;
Queue<Node *> *temp = nodeQueue1;
nodeQueue1 = nodeQueue2;
nodeQueue2 = temp;
while(false == nodeQueue2->isEmpty())
{
currentNode = nodeQueue2->get(); // Dequeue
PRINT_NODE_DATA(currentNode);
if(currentNode->hasLeft())
{
nodeQueue1->put(currentNode->mLeft); // Enqueue
}
if(currentNode->hasRight())
{
nodeQueue1->put(currentNode->mRight);
}
}
cout << endl;
}
return;
}
詞shash
這行代碼在bplus_Enqueue
函數中看起來很奇怪:
queue->next = bplusTemp;
free(bplusTemp);
基本上,您是在隊列使用的鏈表中設置下一個節點,但是在將next
指針分配給鏈表的上一個末尾之后將其釋放。 這意味着您的倒數第二個節點指向的是釋放的內存,而不是有效的鏈表節點,這將在訪問它時導致分段錯誤。 第一行之后,由bplusTemp
節點指向的內存現在已由列表“擁有” ...您不能在該指針上調用free
,否則不能指向該內存的所有其他指針(在這種情況下為queue->next
)也指向已釋放的內存,並且在嘗試訪問該內存時將出現段錯誤。
這對於為什么您能夠打印前兩個節點值(根及其子節點之一)並獲得段錯誤也很有意義。 基本上,當隊列為空時,您永遠不會調用這些行,而是要添加第一個節點。 因此,當您添加root
,您就可以了……您不會對其free
打電話。 然后,將其出隊,然后再將其清空。 因此,將root
的下一個孩子添加到隊列中,這也很好,因為因為隊列為空,所以您不必在bplusNew
上調用free
。 但是現在,當您添加根的任何其他子級並且隊列不為空時,您最終在bplusNew
上調用free
,導致隊列僅包含單個值。 換句話說, queue->next
指向的第一個節點(即鏈表中的第二個節點)實際上不再可用了……您在該內存上稱為free
。
其次,在您的bplus_Dequeue
函數中,存在內存泄漏...特別是在這里:
BPLUS bplusTemp = queue->bplusNode;
queue = queue->next;
您要重新分配鏈表的最前面,而不會釋放作為鏈表原頭的節點。 現在,您不再有指向該節點的指針,並且它被視為內存泄漏。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.