【发布时间】:2021-05-26 08:44:25
【问题描述】:
我正在尝试在 C 中创建一个链表,其中每个节点都连接到右侧和左侧。使用 insert_node 函数,我输入了 4 个节点的值:2、3、5、2
如果我写的逻辑正确,插入节点应该已经自动对列表进行排序,使其对齐为:2,2,3,5
如果我检查 print_list 中的中间值,该值会显示为 3,这正是我的预期。但是,一旦我使用临时节点 temp 移动到左侧节点,temp 就会变为 nullptr。
我不明白为什么会这样,因为 print_list 中的临时节点是用列表的中间节点初始化的,而中间节点被分配了一个左节点。
typedef struct ListNode{
struct ListNode* right;
struct ListNode* left;
int value;
} ListNode;
//a linked list that saves the middle node of the list
typedef struct LinkedList{
ListNode* middle;
int left_size;
int right_size;
}LinkedList;
//a function to reduce repeating malloc
ListNode* init_node() {
return (ListNode*)malloc(sizeof(ListNode*) * 2 + 4);
}
LinkedList* init_list() {
return (LinkedList*)malloc(sizeof(ListNode*) + sizeof(int) * 2);
}
//function to assign NULL to unassigned pointers in structs
void nullify_node(ListNode* node) {
node->left = NULL;
node->right = NULL;
}
void nullify_list(LinkedList* list) {
list->middle = NULL;
}
//sorts the list so that the leftmost node has smallest value
void insert_node(LinkedList* list, int value) {
ListNode* new_node = init_node();
new_node->value = value;
nullify_node(new_node);
printf("initialized new node\n");
//if no node was ever inserted in the list, make the new node be the middle one
if (list->left_size+list->right_size==0) {
list->middle = new_node;
list->right_size += 1;
}
else {
//make a temporary node to traverse the list
ListNode* temp =list->middle;
nullify_node(temp);
printf("initialized temp\n");
//if given value is smaller or equal to that of the middle node, traverse to the left
if (value <= list->middle->value) {
int left_size = list->left_size;
//if no node was ever inserted to the left, make the new node the first left node
if (left_size == 0) {
printf("initialized first left");
list->middle->left=new_node;
list->left_size += 1;
}
else {
//temp->left should be the left node to new node
//traverse temp until temp->left->value is smaller than value while temp->value is bigger than value
for (; left_size > 0; left_size--) {
if (temp->left) {//only if temp->left exist check temp->left->value
//if temp->left->value is bigger than value, hop once more
if (value < temp->left->value) {
temp = temp->left;
}//if it is the same or bigger, stop there.
else {
break;
}
}
}
//put new node between temp->left and temp
if (temp->left) {
new_node->right = temp;
new_node->left = temp->left;
temp->left->right = new_node;
temp->left = new_node;
}
else {//if temp was the leftmost node, make new node be the leftmost node.
new_node->right = temp;
temp->left = new_node;
}
//balance list
list->left_size += 1;
if (list->left_size > list->right_size + 1) {
list->middle = list->middle->left;
list->left_size -= 1;
list->right_size += 1;
}
}
}//traverse to the right side of the list if given value is bigger than the middle node's value
else if (value > list->middle->value) {
int right_size = list->right_size;
//since middle value is considered as one of the right side's nodes, hop minus 1 time than the right_size
for (; right_size > 1; right_size--) {
if (temp->right) {// if temp has a right node, compare temp->right->value with given value
//if given value is bigger, move temp to the right
if (value > temp->right->value) {
temp = temp->right;
}
else {
break;
}
}
}
//if temp wasn't the rightmost node,
if (temp->right) {
//insert new node between temp and temp->right
new_node->left = temp;
new_node->right = temp->right;
temp->right->left = new_node;
temp->right = new_node;
}
else {//if temp was the rightmost node, make the new node be the rightmost node
temp->right = new_node;
new_node->left = temp;
}
//balance list
list->right_size += 1;
if (list->right_size > list->left_size + 1) {
list->middle = list->middle->right;
list->left_size += 1;
list->right_size -= 1;
}
}
}
}
void print_list(LinkedList*list) {
//move to leftmost node
ListNode*temp = list->middle;
printf("middlevalue:%d", temp->value);
for (int i = 0; i < list->left_size ; i++) {
//when input 2, 3, 5, 2, from the second interation temp is nullptr for some reason
temp = temp->left;
printf("%dth value:%d",i, temp->value);
}
for (int j = 0; j < list->left_size + list->right_size; j++) {
printf("\t%d", temp->value);
temp = temp->right;
}
}
【问题讨论】: