在C语言中创建排序链表

在C语言中创建排序链表,c,list,hyperlink,sorted,C,List,Hyperlink,Sorted,我希望创建一个方法,按照PID的升序插入结构 我一直在检查其他线程,我写了一些类似于其他人提到的内容,但在编译时,我遇到了关于Next\u PCB和类型冲突的错误 struct PCB { struct PCB *Next_PCB; int PID; }; struct PCB *ptr, *tmp; void insert_ordered (struct PCB *, struct PCB *); void print_list(struct PCB *); main()

我希望创建一个方法,按照PID的升序插入结构

我一直在检查其他线程,我写了一些类似于其他人提到的内容,但在编译时,我遇到了关于
Next\u PCB
和类型冲突的错误

struct PCB
{
    struct PCB *Next_PCB;
    int PID;
};

struct PCB *ptr, *tmp;

void insert_ordered (struct PCB *, struct PCB *);
void print_list(struct PCB *);

main()
{
    int num_structs, i;
    ptr = (struct PCB *) malloc (sizeof (struct PCB));
    num_structs = 10 + (rand() % 10);
    for ( i = 0; i < num_structs; i++)
    {
        tmp = (struct PCB *) malloc (sizeof(struct PCB));
        tmp->PID = rand() % 20;
        tmp->Next_PCB = NULL;
        insert_ordered(ptr, tmp);
    }
    print_list(ptr);
}

void insert_ordered (struct PCB *Head, struct PCB *Add)
{
    struct PCB* new;
    if(*Head == NULL || *Head->PID >= Add->PID)
    {
        Add->Next_PCB = *Head;
        *Head = Add;
    }
    else
    {
        new = *Head;
        while (new ->Next_PCB!=NULL && new->Next_PCB->PID < Add -> PID)
        {
            new = new->Next_PCB;
        }
        Add->Next_PCB = new->Next_PCB;
        new->Next_PCB = Add;
    }
}
结构PCB { 结构PCB*下一块PCB; int-PID; }; 结构PCB*ptr,*tmp; 已订购无效插件(结构PCB*,结构PCB*); 无效打印列表(结构PCB*); main() { int num_结构,i; ptr=(结构PCB*)malloc(sizeof(结构PCB)); num_structs=10+(rand()%10); 对于(i=0;iPID=rand()%20; tmp->Next_PCB=NULL; 插入订单(ptr、tmp); } 打印列表(ptr); } 已订购无效插件(结构PCB*头部,结构PCB*添加) { 结构PCB*新; 如果(*Head==NULL | |*Head->PID>=Add->PID) { 添加->下一个印刷电路板=*磁头; *头=加; } 其他的 { 新=*头; while(新建->下一块PCB!=NULL&&new->下一块PCB->PIDPID) { 新建=新建->下一个PCB; } 添加->下一个印刷电路板=新建->下一个印刷电路板; 新建->下一个印刷电路板=添加; } }
函数
insert\u ordered
是问题发生的地方,我处理结构的方式是导致问题的原因,因此我很好奇我在方法本身和结构方面做错了什么。

你在问为什么编译器不喜欢insert\u ordered()中的代码

当我将您的代码提供给GCC时,它的函数出现了5个问题,所有这些问题都是因为您将
*Head
视为指针,而它是
struct PCB
的实例

*Head
不是指针,要使其成为指针,函数原型应具有
struct PCB**Head
。然后,
Head
是指向指针的指针:它指向调用者拥有的变量,该变量又是指向列表头的指针

因此,代码是:

void insert_ordered (struct PCB **Head, struct PCB *Add)
{
  struct PCB* new;
  if ((*Head == NULL) || ((*Head)->PID >= Add->PID))
  {
    Add->Next_PCB = *Head;
    *Head = Add;
  }
  else
  {
    new = *Head;
    while ((new->Next_PCB != NULL) && (new->Next_PCB->PID < Add->PID))
    {
      new = new->Next_PCB;
    }
    Add->Next_PCB = new->Next_PCB;
    new->Next_PCB = Add;
  }
}
void insert\u订购(结构PCB**头部,结构PCB*添加)
{
结构PCB*新;
如果((*Head==NULL)| |((*Head)->PID>=Add->PID))
{
添加->下一个印刷电路板=*磁头;
*头=加;
}
其他的
{
新=*头;
而((新建->下一个PCB!=NULL)&&(新建->下一个PCB->PIDPID))
{
新建=新建->下一个PCB;
}
添加->下一个印刷电路板=新建->下一个印刷电路板;
新建->下一个印刷电路板=添加;
}
}
当然,insert_ordered()的调用必须更改为
insert_ordered(&ptr,tmp)

这是可行的,但正如本吉所说,这不是一个很好的算法。我假设这是一个学习练习,在下一课中,您将看到一个二叉树


顺便说一下,在
if((*Head==NULL)| |((*Head)->PID>=Add->PID))
I添加了一些不必要的括号。这是因为,虽然没有括号的代码对编译器来说是明确的,但它使我的一些同事感到困惑。额外的括号使它更可读。。。除非你吃的太多。但是需要
(*Head)->PID中的括号。

至少有几个问题我可能没有全部找到,但我看到的是:

  • 您需要能够在插入例程中更改头指针的值。由于您已经在执行诸如“*Head==NULL”之类的操作,因此您的insert例程似乎就是为此编写的。您需要知道的是正确地声明它为“struct PCB**Head”,并正确地传递它为“insert_ordered(&ptr,tmp)”
  • 您需要正确处理初始ptr值。您正在为它占用空间,但没有在其中放置任何内容。相反,您应该将该malloc替换为NULL赋值:“ptr=NULL”

对链接列表进行排序通常是一个非常糟糕的主意。最有效的方法是O(n^2),而将数据复制到数组、对数组进行排序并复制回列表的方法是O(n*log(n))。这将进行编译,但对Head的赋值:“Head=Add”除了更改一个被忽略的局部变量外,什么都做不了。@Brad-D'Oh,我不应该让我在这么晚的时候靠近计算机。我对我的答案进行了编辑,以避免以后在这里看到的人感到困惑。谢谢