Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的结构链表连接不好_C_Algorithm - Fatal编程技术网

C中的结构链表连接不好

C中的结构链表连接不好,c,algorithm,C,Algorithm,我试图在C中创建一个链表,其中每个节点都有到左右两侧的连接。使用insert_node函数,我输入了4个节点的值:2、3、5、2 如果我将逻辑写在右边,则insert节点应该自动对列表进行排序,使其对齐为:2,2,3,5 如果我检查print_列表中的中间值,该值将显示为3,这是我所期望的。但是,只要我使用临时节点temp移动到左侧节点,temp就会变成nullptr 我不明白为什么会发生这种情况,因为print_列表中的temp节点是用列表的中间节点初始化的,中间节点被分配了一个左节点 typ

我试图在C中创建一个链表,其中每个节点都有到左右两侧的连接。使用insert_node函数,我输入了4个节点的值:2、3、5、2

如果我将逻辑写在右边,则insert节点应该自动对列表进行排序,使其对齐为:2,2,3,5

如果我检查print_列表中的中间值,该值将显示为3,这是我所期望的。但是,只要我使用临时节点temp移动到左侧节点,temp就会变成nullptr

我不明白为什么会发生这种情况,因为print_列表中的temp节点是用列表的中间节点初始化的,中间节点被分配了一个左节点

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;
    }
}
typedef结构列表节点{
结构ListNode*右;
结构ListNode*左;
int值;
}列表节点;
//保存列表中间节点的链接列表
类型定义结构链接列表{
ListNode*中间;
int左_大小;
int右_大小;
}链接列表;
//减少重复malloc的函数
ListNode*init_node(){
return(ListNode*)malloc(sizeof(ListNode*)*2+4);
}
LinkedList*初始列表(){
return(LinkedList*)malloc(sizeof(ListNode*)+sizeof(int)*2;
}
//函数将NULL赋值给结构中未赋值的指针
void nullify_节点(ListNode*节点){
节点->左=空;
节点->右=空;
}
无效无效列表(LinkedList*列表){
列表->中间=空;
}
//对列表进行排序,使最左侧的节点具有最小值
void insert_节点(LinkedList*列表,int值){
ListNode*new_node=init_node();
新建_节点->值=值;
取消_节点(新_节点);
printf(“初始化的新节点\n”);
//如果列表中从未插入任何节点,请将新节点设为中间节点
如果(列表->左\u大小+列表->右\u大小==0){
列表->中间=新建_节点;
列表->右键大小+=1;
}
否则{
//创建临时节点以遍历列表
ListNode*temp=list->middle;
取消_节点(temp);
printf(“初始化的温度\n”);
//如果给定值小于或等于中间节点的值,则向左遍历
如果(值中间->值){
int left_size=列表->left_size;
//如果从未在左侧插入任何节点,请将新节点设为第一个左侧节点
如果(左_大小==0){
printf(“左一初始化”);
列表->中间->左侧=新建_节点;
列表->左_大小+=1;
}
否则{
//temp->left应该是新节点的左侧节点
//遍历temp,直到temp->left->value小于value,而temp->value大于value
对于(;左侧大小>0;左侧大小--){
如果(临时->左){//仅当临时->左存在时检查临时->左->值
//如果临时->左->值大于该值,请再次跳转
如果(值left->value){
温度=温度->左侧;
}//如果它是相同或更大的,停在那里。
否则{
打破
}
}
}
//将新节点置于临时->左侧和临时之间
如果(临时->左){
新建节点->右=临时;
新建节点->左=临时->左;
临时->左->右=新节点;
temp->left=新建_节点;
}
else{//如果temp是最左边的节点,则将新节点设为最左边的节点。
新建节点->右=临时;
temp->left=新建_节点;
}
//余额表
列表->左_大小+=1;
如果(列表->左侧大小>列表->右侧大小+1){
列表->中间=列表->中间->左侧;
列表->左侧大小-=1;
列表->右键大小+=1;
}
}
}//如果给定值大于中间节点的值,则遍历到列表的右侧
else if(值>列表->中间->值){
int right\u size=列表->right\u size;
//由于中间值被视为右侧的节点之一,因此跳数比右侧的大小减去1倍
对于(;右侧大小>1;右侧大小--){
如果(temp->right){//如果temp有一个右节点,则将temp->right->值与给定值进行比较
//如果给定值较大,则将temp移到右侧
如果(值>温度->右侧->值){
温度=温度->右侧;
}
否则{
打破
}
}               
}
//如果temp不是最右边的节点,
如果(临时->右侧){
//在临时和临时之间插入新节点->右侧
新建节点->左=临时;
新建节点->右=临时->右;
临时->右->左=新节点;
temp->right=新节点;
}
else{//如果temp是最右边的节点,则将新节点设为最右边的节点
temp->right=新节点;
新建节点->左=临时;
}
//余额表
列表->右键大小+=1;
如果(列表->右侧大小>列表->左侧大小+1){
列表->中间=列表->中间->右侧;
列表->左_大小+=1;
列表->右键大小-=1;
}
}
}
}
作废打印列表(链接列表*列表){
//移动到最左边的节点
ListNode*temp=list->middle;
printf(“中间值:%d”,临时值->值);
对于(int i=0;ileft\u size;i++){
//当来自第二个交互温度的输入2、3、5、2对于某些re为空PTR时
ListNode *init_node(int value) // note argument
{
    ListNode * p = malloc(sizeof *p);
    p->left = p->right = NULL;
    p->value = value;
    return p;
}

LinkedList *init_list()
{
    LinkedList *p = malloc(sizeof *p);
    p->left_size = p->right_size = 0;
    p->middle = NULL;
    return p;
}
ListNode* new_node = init_node();
new_node->value = value;
nullify_node(new_node);
ListNode *new_node = init_node(value);
//make a temporary node to traverse the list
ListNode *temp = list->middle;
nullify_node(temp);
printf("initialized temp\n");
nullify_node(temp);
void print_list(const LinkedList *list)
{
    //move to leftmost node
    const ListNode *temp = list->middle;
    if (temp)
    {
        while (temp->left)
            temp = temp->left;
    }

    while (temp)
    {
        printf("%d ", temp->value);
        temp = temp->right;
    }
}