【问题标题】:linked list sort problems链表排序问题
【发布时间】:2014-06-06 06:53:17
【问题描述】:

我正在尝试使用冒泡排序对链表进行排序。我也不能只交换节点内的值。我一直在画图,试图弄清楚如何在没有帮助的情况下自己完成,但我开始头疼,不知道为什么这行不通。

void sort_ascending(struct node ** head){
  int x;
  struct node*temp;
  struct node*temp2;
  x = length(*head)+1;    //checks if more than one node is in the list
  if(x < 2){
    printf("1 or less\n");
    //free(temp);
    return;
  }
  printf("longer than 1\n");
  printf("%d %d\n", (*head)->val, (*head)->next->val);
  if((*head)->val > (*head)->next->val){
    printf("needs to sort!\n");
    temp = (*head)->next->next; //sets temp to the node after the two nodes being swapped
    printf("test1\n");
    temp2 = (*head); //sets temp2 to the node1
    printf("test2\n");
    *head = (*head)->next; //changes head to point at node2 instead of node1
    printf("test3\n");
    (*head)->next = temp2; //sets node2 to point to node1
    (*head)->next->next = temp; //sets node2 to point back into the list
    printf("test4\n");
    //free(temp);
  }
}

现在我只是想对两个节点进行排序。在我能得到这个工作之后,我会把它变成一个循环。由于某种原因,它甚至没有对前两个元素进行排序。

以下是我的一些其他功能,以帮助理解:

结构定义:

struct node {
int val;
struct node *next;

};

其他功能:

void push(struct node ** headRef, int data){
struct node* newNode =  malloc(sizeof(struct node)); //alocates space on heap
printf("pushed node\n");
newNode->val = data;//sets data value
printf("%d\n", newNode->val);
newNode->next = *headRef; // The '*' to dereferences back to the real head
*headRef = newNode; // ditto

};

void print(struct node * head, int length){
int x = 0;
printf("tried to print\n");
//struct node*temp = head;

//while(head->next != NULL){
while (x < length + 1){
    printf("ran loop\n");
    printf("%d\n", head->val);
    printf("got number\n");
    head = head->next;
    x++;
}
printf("done with loop\n");

}

int main(){
char ans;
int num;
struct node *head = NULL;
do {
    do {
        printf("Enter a number: ");
        scanf("%d", &num);
        push(&head, num);//Can change to append for back

        printf("Do you want another num (y or n): ");
        scanf("%1s", &ans);
    } while (ans == 'y');

    printf("Sort ascending or descending (a or d)? ");
    scanf("%1s", &ans);
    if(ans == 'a') sort_ascending(&head);
    //else if(ans == 'd') sort_descending(&head);

    print(head, length(head));

    printf("Do you want to do this again (y or n)? ");
    scanf("%1s", &ans);
    if (ans == 'y') clear(&head);

} while (ans == 'y');


return 0;

}

int length(struct node* head){
int length = 0;
//struct node*temp = head;
printf("tried to find length\n");
while (head->next != NULL){
    length++;
    head = head->next;
}
printf("%d\n", length + 1);
return length;

}

【问题讨论】:

  • 你是怎么调用这个函数的?你如何测试看看这是否有效?
  • 在我创建了两个节点之后,比如说一个值为 5 和一个值为 6,我调用这个函数来对我创建的节点进行排序。如果它重新排列它们,我不知道它有效
  • 我知道您了解排序的工作原理。 :) 我想知道 1) 您是如何构建节点的(向我们展示您的代码),以及 2) 如果您在调试器中检查值或将它们打印到屏幕上以测试这是否有效。
  • @WernerHenze 虽然您的 malloc 声明是正确的,但 OP 确实声明他现在只尝试对前两个元素进行排序,稍后会添加循环。
  • 感谢您提供 malloc 信息,我将删除它们。

标签: c sorting linked-list


【解决方案1】:

所以,让我们总结一下。

函数长度减1。

int length(struct node* head){
    int length = 0;
    while (head != NULL){
        ++length;
        head = head->next;
    }
    return length;
}

函数 print 打印太多了。

void print(struct node * head, int length){
    int x;
    for(x = 0; x < length; ++x){
        printf("%d\n", head->val);
        head = head->next;
    }
}

而且您的 scanf 正在破坏内存。带有“%1s”的 scanf 需要一个指向至少两个字符的指针,一个是要存储的,一个是尾随的空字节。因此,您需要提供两个字符 (char ans[2];),或者更好的解决方案是将一个字符读取为一个字符。

char ans;
scanf("%c", &ans);

另外,如前所述,don't cast the return value of malloc 如果您使用 C 编程。

如果您想知道为什么我将您的后缀 ++(如 x++)更改为前缀 ++(如 ++x):我是一名 C++ 程序员,对于 C++,建议使用前缀 ++ 而不是后缀 ++出于性能原因(与 int 或指针无关,但与迭代器等复杂类型有关)。

【讨论】:

    猜你喜欢
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多