ing 发表于 2020-3-9 23:37

C 链表排序

本帖最后由 ing 于 2020-3-11 21:00 编辑

当我让2个指针(p 和 指针integrate)建立关系后,p指针删除元素,integrate也会减少


现在,删除一个元素,发现2个指针的内容都减少了



但是这里却不会,main 指针和 b1指针建立了关系


b1多次删去元素之后,发现只有会b1减少了元素


___________________________________________________
问题由此引起
p->next = p->next->next;
改成 p = p->next 就不会出现这种情况


```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define KeyType int
#define Block 2

typedef struct link
{
      KeyType data;
      struct link *next;
}Link;

typedef struct
{
      KeyType key;
      int start;
}newIndex;

void initLink(int array[], int start, int length, Link **p)
{
      *p = (Link*)malloc(sizeof(Link));
      Link *temp = *p;

      //结束位置等于 总长度/分成的块数+起始位置
      int e = length/Block + start;
      for (size_t i = start; i < e; i++)
      {
                Link *a = (Link*)malloc(sizeof(Link));
                a->data = array;
                a->next = NULL;

                temp->next = a;
                temp = temp->next;
      }
}

void merge(Link **main, Link *b1, Link *b2)
{
      *main = b1;

      while (b1->next)
      {
                b1 = b1->next;
      }
               
      while (b2)
      {
                b1->next = b2->next;
                b1 = b1->next;
                b2 = b2->next;
      }
}

void swap(Link **integrate, int length)
{
      Link *p = *integrate;

      for (size_t i = 1; i < length; i++)
      {
                for (size_t j = 1; j < length; j++)
                {
                        if (p->next->data > p->next->next->data)
                        {
                              Link *temp = p->next;
                              p->next->data = p->next->next->data;
                              p->next->next->data = temp->data;
                        }
                        p->next = p->next->next;
                        p->next->next = p->next->next->next;
                        if (!p->next->next) break;
                }
      }
}

void main()
{
      int a[] = { 33, 42, 44, 38, 24, 48, 22, 12, 13,
                              8, 9, 20, 60, 58, 74, 49, 86, 53
                              };
      Link *a1, *a2;
      initLink(a, 0, 18, &a1);
      initLink(a, 9, 18, &a2);
      
      Link *integrate;
      merge(&integrate,a1,a2);
      
      swap(&integrate,18);

}

```

atlas.吾爱破解 发表于 2020-3-10 07:08

因为C语言的指针本身就是地址传递,变一个也会导致另一个跟着变

行星波动 发表于 2020-3-10 11:05

本帖最后由 行星波动 于 2020-3-10 11:37 编辑

楼主这个代码的问题好像有点多。。
首先p->next没有删掉节点只是指针后移了,你再怎末移动指针对这个地址上的值没影响的,看起来integrate值变了应该是交换的问题(不太确定,没仔细分析)
temp的问题的话。。。你设置的temp也是个指针。它指向的是你p的后面一个结点的地址,这很重要,因为你下一句改变了p的下一个节点的data,也就是说temp指向的data变了
说起来有点麻烦,我画个图帮助楼主理解下

可以选择设置temp为int类型只保存data值,这样就不会导致值丢失了
还有就是个人觉得楼主的循环挺绕的,我一直没转过弯来,改了两下结果出现野指针了。。我又重写了一遍代码希望可以帮到楼主void swap(Link* integrate, int length)
{
        integrate = integrate->next;
        Link* p = integrate;
        Link* head = integrate;
        for (int i = 1; i < length; i++)
        {
                for(int j=1;j<length;j++)
                {
                        if (p->data > p->next->data)
                        {
                                int temp = p->next->data;
                                p->next->data = p->data;
                                p->data = temp;
                        }
                        print(head);
                        p = p->next;
                }
       
                p = integrate;
               
        }
}

另外我也是刚入坑小白,有哪里不对的,不好的还希望大佬们多多指正:rggrg

ing 发表于 2020-3-11 21:15

行星波动 发表于 2020-3-10 11:05
楼主这个代码的问题好像有点多。。
首先p->next没有删掉节点只是指针后移了,你再怎末移动指针对这个地址 ...
我发现我的问题(参数中的指针 **integrate 后移)是由
p->next = p->next->next
引起的了,可我没理解这是为什么

p 是指针类型,p->next 也是指针,并且指针地址全都是不同的,为什么
p = p->next 不会导致参数中的指针 **integrate 后移?

然后,这是循环的思想,外层循环是 起泡次数,内层循环是 比较次数

古月不傲 发表于 2020-3-11 21:58

本帖最后由 古月不傲 于 2020-3-11 22:14 编辑

ing 发表于 2020-3-11 21:15
我发现我的问题(参数中的指针 **integrate 后移)是由
p->next = p->next->next
引起的了,可我没理解 ...
void swap(Link **integrate, int length)
{
      Link *p = *integrate;
      for (size_t i = 1; i < length; i++)
      {
               for (size_t j = 1; j < length; j++)
                {
                        if (p->next->data > p->next->next->data)
                        {
                              Link *temp = p->next;
                              p->next->data = p->next->next->data;
                              p->next->next->data = temp->data;
                        }
                        p = p->next;
                        //p->next->next = p->next->next->next;
                        if (p->next->next == NULL)
                              p = *integrate;
                              break;
                }
      }
}
就算最后地址不为NULL 你成功了
但是指针还是动了 你第二次循环就已经错了 下一个元素早已经变化
页: [1]
查看完整版本: C 链表排序