鱼C论坛

 找回密码
 立即注册
楼主: 2985675302

[已解决]快速排序C语言

  [复制链接]
 楼主| 发表于 2023-12-15 19:58:25 | 显示全部楼层
FishC 发表于 2023-12-15 19:54
在函数调用中,当传递结构体作为参数时,通常使用结构体的指针来传递,而不是直接进行复制。可以使用`&` ...

可以写规整一点吗,有点乱
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 19:58:41 | 显示全部楼层
2985675302 发表于 2023-12-15 19:58
可以写规整一点吗,有点乱

当我们需要在函数调用中传递结构体作为参数时,通常使用结构体的指针进行传递,而不是直接复制整个结构体。我们可以使用`&`运算符来获取结构体变量的地址,并将其传递给函数。下面是一个示例代码:
  1. #include <stdio.h>
  2. // 定义结构体
  3. struct Person {
  4.     char name[20];
  5.     int age;
  6. };
  7. // 函数接收结构体指针作为参数
  8. void printPerson(const struct Person* p) {
  9.     printf("Name: %s\n", p->name);
  10.     printf("Age: %d\n", p->age);
  11. }
  12. int main() {
  13.     // 创建结构体变量
  14.     struct Person p1 = {"Alice", 25};
  15.    
  16.     // 将结构体变量的地址传递给函数
  17.     printPerson(&p1);
  18.    
  19.     return 0;
  20. }
复制代码

在这个例子中,我们定义了一个名为`Person`的结构体,并在`main`函数中创建了一个`Person`类型的变量`p1`。然后,我们将`p1`的地址通过`&`运算符传递给`printPerson`函数。在`printPerson`函数中,我们使用指针引用操作符(`->`)来访问结构体成员。这样,我们就可以在函数中打印出结构体的信息。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-15 20:01:36 | 显示全部楼层
FishC 发表于 2023-12-15 19:58
当我们需要在函数调用中传递结构体作为参数时,通常使用结构体的指针进行传递,而不是直接复制整个结构体 ...

用一个链表来演示呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 20:02:13 | 显示全部楼层
2985675302 发表于 2023-12-15 20:01
用一个链表来演示呢

好的,下面是一个使用链表实现快速排序的示例代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // 定义链表结点
  4. struct Node {
  5.     int data;
  6.     struct Node* next;
  7. };
  8. // 创建新结点
  9. struct Node* newNode(int data) {
  10.     struct Node* node = (struct Node*)malloc(sizeof(struct Node));
  11.     node->data = data;
  12.     node->next = NULL;
  13.     return node;
  14. }
  15. // 分割链表,并返回分割点
  16. struct Node* partition(struct Node* head, struct Node* end, struct Node** newHead, struct Node** newEnd) {
  17.     struct Node* pivot = end;
  18.     struct Node* prev = NULL;
  19.     struct Node* cur = head;
  20.     struct Node* tail = pivot;
  21.     while (cur != pivot) {
  22.         if (cur->data < pivot->data) {
  23.             if (*newHead == NULL) {
  24.                 *newHead = cur;
  25.             }
  26.             prev = cur;
  27.             cur = cur->next;
  28.         } else {
  29.             if (prev) {
  30.                 prev->next = cur->next;
  31.             }
  32.             struct Node* temp = cur->next;
  33.             cur->next = NULL;
  34.             tail->next = cur;
  35.             tail = cur;
  36.             cur = temp;
  37.         }
  38.     }
  39.     if (*newHead == NULL) {
  40.         *newHead = pivot;
  41.     }
  42.     *newEnd = tail;
  43.     return pivot;
  44. }
  45. // 快速排序链表
  46. struct Node* quickSort(struct Node* head, struct Node* end) {
  47.     if (!head || head == end) {
  48.         return head;
  49.     }
  50.     struct Node* newHead = NULL;
  51.     struct Node* newEnd = NULL;
  52.     struct Node* pivot = partition(head, end, &newHead, &newEnd);
  53.     if (newHead != pivot) {
  54.         struct Node* temp = newHead;
  55.         while (temp->next != pivot) {
  56.             temp = temp->next;
  57.         }
  58.         temp->next = NULL;
  59.         newHead = quickSort(newHead, temp);
  60.         temp = newHead;
  61.         while (temp->next) {
  62.             temp = temp->next;
  63.         }
  64.         temp->next = pivot;
  65.     }
  66.     pivot->next = quickSort(pivot->next, newEnd);
  67.     return newHead;
  68. }
  69. // 打印链表
  70. void printList(struct Node* head) {
  71.     while (head) {
  72.         printf("%d ", head->data);
  73.         head = head->next;
  74.     }
  75.     printf("\n");
  76. }
  77. int main() {
  78.     // 创建链表
  79.     struct Node* head = newNode(4);
  80.     head->next = newNode(2);
  81.     head->next->next = newNode(1);
  82.     head->next->next->next = newNode(3);
  83.     printf("原始链表:");
  84.     printList(head);
  85.     head = quickSort(head, NULL);
  86.     printf("排序后链表:");
  87.     printList(head);
  88.     return 0;
  89. }
复制代码

在这个例子中,我们先定义了一个链表结点`Node`,其中包含一个整数型的数据成员和指向下一个结点的指针。然后,我们实现了`newNode`函数用于创建新结点。

接下来,我们定义了两个辅助函数`partition`和`quickSort`。`partition`函数用于分割链表,并返回分割点,它接收链表的头结点、尾结点和两个指针的指针作为参数(用于更新链表的头结点和尾结点)。

`quickSort`函数用于快速排序链表,它递归地调用`partition`函数,并根据分割点将链表划分为两部分进行排序。

最后,在`main`函数中,我们创建了一个包含4个结点的链表,并调用`quickSort`函数对链表进行排序,并打印排序后的链表。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-15 20:05:01 | 显示全部楼层
FishC 发表于 2023-12-15 20:02
好的,下面是一个使用链表实现快速排序的示例代码:

可以打上注释吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 20:05:33 | 显示全部楼层

当然可以,下面是已经加上注释的代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // 定义链表结点
  4. struct Node {
  5.     int data;
  6.     struct Node* next;
  7. };
  8. // 创建新结点
  9. struct Node* newNode(int data) {
  10.     struct Node* node = (struct Node*)malloc(sizeof(struct Node));
  11.     node->data = data;
  12.     node->next = NULL;
  13.     return node;
  14. }
  15. // 分割链表,并返回分割点
  16. struct Node* partition(struct Node* head, struct Node* end, struct Node** newHead, struct Node** newEnd) {
  17.     struct Node* pivot = end; // 选取最后一个结点作为基准点
  18.     struct Node* prev = NULL; // 记录当前结点的前一个结点
  19.     struct Node* cur = head; // 用于遍历链表
  20.     struct Node* tail = pivot; // 记录分割点的尾结点
  21.     while (cur != pivot) {
  22.         if (cur->data < pivot->data) {
  23.             if (*newHead == NULL) {
  24.                 *newHead = cur; // 分割点前面的结点作为新的头结点
  25.             }
  26.             prev = cur;
  27.             cur = cur->next;
  28.         } else {
  29.             if (prev) {
  30.                 prev->next = cur->next;
  31.             }
  32.             struct Node* temp = cur->next;
  33.             cur->next = NULL;
  34.             tail->next = cur; // 将大于等于基准点的结点放在分割点后面
  35.             tail = cur;
  36.             cur = temp;
  37.         }
  38.     }
  39.     if (*newHead == NULL) {
  40.         *newHead = pivot; // 当分割点为链表的头结点时
  41.     }
  42.     *newEnd = tail; // 更新分割点的尾结点
  43.     return pivot;
  44. }
  45. // 快速排序链表
  46. struct Node* quickSort(struct Node* head, struct Node* end) {
  47.     if (!head || head == end) {
  48.         return head;
  49.     }
  50.     struct Node* newHead = NULL; // 新的头结点
  51.     struct Node* newEnd = NULL; // 新的尾结点
  52.     struct Node* pivot = partition(head, end, &newHead, &newEnd); // 进行分割
  53.     if (newHead != pivot) { // 如果分割点不是头结点,递归排序前半部分
  54.         struct Node* temp = newHead;
  55.         while (temp->next != pivot) {
  56.             temp = temp->next;
  57.         }
  58.         temp->next = NULL;
  59.         newHead = quickSort(newHead, temp);
  60.         temp = newHead;
  61.         while (temp->next) {
  62.             temp = temp->next;
  63.         }
  64.         temp->next = pivot;
  65.     }
  66.     pivot->next = quickSort(pivot->next, newEnd); // 递归排序后半部分
  67.     return newHead;
  68. }
  69. // 打印链表
  70. void printList(struct Node* head) {
  71.     while (head) {
  72.         printf("%d ", head->data);
  73.         head = head->next;
  74.     }
  75.     printf("\n");
  76. }
  77. int main() {
  78.     // 创建链表
  79.     struct Node* head = newNode(4);
  80.     head->next = newNode(2);
  81.     head->next->next = newNode(1);
  82.     head->next->next->next = newNode(3);
  83.     printf("原始链表:");
  84.     printList(head);
  85.    
  86.     head = quickSort(head, NULL); // 对链表进行快速排序
  87.     printf("排序后链表:");
  88.     printList(head);
  89.     return 0;
  90. }
复制代码

希望这个加上注释的示例代码能够更加清晰地帮助你理解快速排序在链表中的实现。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-15 20:09:46 | 显示全部楼层
FishC 发表于 2023-12-15 20:05
当然可以,下面是已经加上注释的代码:

换一个简单的链表例子
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 20:10:02 | 显示全部楼层
2985675302 发表于 2023-12-15 20:09
换一个简单的链表例子

好的,这里有一个简单的链表例子供你参考:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. struct Node {
  4.     int data;
  5.     struct Node* next;
  6. };
  7. // 创建新结点
  8. struct Node* newNode(int data) {
  9.     struct Node* node = (struct Node*)malloc(sizeof(struct Node));
  10.     node->data = data;
  11.     node->next = NULL;
  12.     return node;
  13. }
  14. // 打印链表
  15. void printList(struct Node* head) {
  16.     struct Node* current = head;
  17.     while (current != NULL) {
  18.         printf("%d ", current->data);
  19.         current = current->next;
  20.     }
  21.     printf("\n");
  22. }
  23. int main() {
  24.     // 创建链表
  25.     struct Node* head = newNode(3);
  26.     head->next = newNode(1);
  27.     head->next->next = newNode(4);
  28.     head->next->next->next = newNode(2);
  29.     printf("原始链表:");
  30.     printList(head);
  31.     // 快速排序链表
  32.     // 此处省略快速排序代码,你可以使用之前的代码进行排序
  33.     printf("排序后链表:");
  34.     printList(head);
  35.     return 0;
  36. }
复制代码

在这个例子中,我们创建了一个包含四个结点的链表,并实现了打印链表的函数。你可以在快速排序部分使用之前提供给你的快速排序代码。运行程序后,你将看到原始链表和排序后的链表结果。希望这个例子对你有所帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-15 20:11:56 | 显示全部楼层
FishC 发表于 2023-12-15 20:10
好的,这里有一个简单的链表例子供你参考:

打印结果是什么
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 20:12:06 | 显示全部楼层

打印结果将会是:

原始链表:3 1 4 2
排序后链表:1 2 3 4

这里的原始链表是按照创建顺序来的,排序后的链表则是按照升序排列的。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-15 21:03:31 | 显示全部楼层
FishC 发表于 2023-12-15 20:12
打印结果将会是:

原始链表:3 1 4 2

C语言中exit怎么用
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 21:03:47 | 显示全部楼层

在C语言中,可以使用`exit()`函数来终止程序的执行。`exit()`函数接受一个整型参数作为退出状态码,表示程序的结束状态。一般情况下,0表示程序正常结束,而非零值则通常表示程序异常终止或出错。

下面是一个示例代码,演示如何使用`exit()`函数:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main() {
  4.     int number;
  5.    
  6.     printf("请输入一个数字:");
  7.     scanf("%d", &number);
  8.    
  9.     if (number < 0) {
  10.         printf("输入的数字不能小于0\n");
  11.         exit(1); // 异常终止,退出状态码为1
  12.     }
  13.    
  14.     printf("输入的数字是:%d\n", number);
  15.    
  16.     return 0; // 正常结束,退出状态码为0
  17. }
复制代码

当输入一个小于0的数字时,程序会输出错误提示信息并使用`exit(1)`来终止程序的执行,退出状态码为1。而如果输入的数字大于等于0,则会正常结束,退出状态码为0。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-15 21:15:10 | 显示全部楼层
FishC 发表于 2023-12-15 21:03
在C语言中,可以使用`exit()`函数来终止程序的执行。`exit()`函数接受一个整型参数作为退出状态码,表示 ...

exit退出的是一个函数还是整个代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 21:15:20 | 显示全部楼层
2985675302 发表于 2023-12-15 21:15
exit退出的是一个函数还是整个代码

`exit()`函数是用来终止整个程序的执行,而不仅仅是退出某个函数。当调用`exit()`函数时,程序会立即终止当前的执行,并返回到操作系统。因此,`exit()`函数应该谨慎使用,并且要确保在适当的时候调用。一般情况下,`exit()`函数会在程序中遇到某种错误或者满足特定条件时被调用,用来提前结束程序的执行。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-15 21:19:17 | 显示全部楼层
FishC 发表于 2023-12-15 21:15
`exit()`函数是用来终止整个程序的执行,而不仅仅是退出某个函数。当调用`exit()`函数时,程序会立即终止 ...

void类型函数如何中途退出
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 21:19:35 | 显示全部楼层
2985675302 发表于 2023-12-15 21:19
void类型函数如何中途退出

在C语言中,void类型的函数并不能直接使用`return`语句来中途退出。因为void类型的函数不返回任何值,没有返回值可供终止程序的其他部分使用。

如果你想要在void类型的函数中中途退出,可以使用`return`语句并不给它传递任何值,或者使用`exit()`函数来终止整个程序的执行。下面是两种方法的示例:

1. 使用空的`return`语句:
  1. #include <stdio.h>
  2. void myFunction() {
  3.    // 执行一些操作
  4.    if (someCondition) {
  5.       return; // 中途退出
  6.    }
  7.    
  8.    // 执行其它操作
  9. }
  10. int main() {
  11.    myFunction();
  12.    // 继续执行后续操作
  13.    printf("程序继续执行\n");
  14.    return 0;
  15. }
复制代码

2. 使用`exit()`函数:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. void myFunction() {
  4.    // 执行一些操作
  5.    if (someCondition) {
  6.       exit(0); // 终止整个程序
  7.    }
  8.    
  9.    // 执行其它操作
  10. }
  11. int main() {
  12.    myFunction();
  13.    // 下面的代码将不会被执行
  14.    printf("程序继续执行\n");
  15.    return 0;
  16. }
复制代码

注意,在使用`exit()`函数时,需要包含`stdlib.h`头文件。此外,`exit()`函数的参数表示程序的返回码,通常使用0表示正常退出,使用其他值表示异常退出。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-15 21:22:09 | 显示全部楼层
FishC 发表于 2023-12-15 21:19
在C语言中,void类型的函数并不能直接使用`return`语句来中途退出。因为void类型的函数不返回任何值,没 ...

如何快速掌握卡特兰数的意义
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 21:22:31 | 显示全部楼层
2985675302 发表于 2023-12-15 21:22
如何快速掌握卡特兰数的意义

卡特兰数是一系列的整数,用于在组合数学和计算几何等领域中进行计数。它们被广泛应用于各种问题中,如括号匹配、二叉树的计数、凸多边形的划分等。

要快速掌握卡特兰数的意义,可以采取以下步骤:

1. 了解卡特兰数的定义:卡特兰数是由欧仁·查尔斯·卡特兰(Eugène Charles Catalan)在19世纪提出的。卡特兰数的递推公式为C(0) = 1,C(n+1) = (4n+2)/(n+2) * C(n),其中n表示数列的索引。

2. 理解卡特兰数的应用:卡特兰数出现在许多组合问题中,其值表示了某种排列或组合的数量。例如,当有n对括号时,卡特兰数C(n)表示了括号正确匹配的不同方式的数量。

3. 学习卡特兰数的性质:卡特兰数具有一些重要的性质,如对称性、递推性和乘法公式。研究这些性质可以帮助你更深入地理解和应用卡特兰数。

4. 探索卡特兰数的应用领域:除了括号匹配,卡特兰数在计算几何、组合数学、图论等领域中也有广泛的应用。通过学习相关问题和案例,你可以更好地理解和应用卡特兰数。

5. 解决一些具体的问题:尝试使用卡特兰数解决一些具体问题,如生成所有合法的括号序列、计算给定n个节点的二叉树的数量等。通过实际操作,你将更深入地理解卡特兰数的意义和应用。

最重要的是,要不断练习和实践。掌握卡特兰数需要时间和经验,但只要持之以恒,你将能够更好地理解和应用它们。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-12-15 21:30:30 | 显示全部楼层
FishC 发表于 2023-12-15 21:22
卡特兰数是一系列的整数,用于在组合数学和计算几何等领域中进行计数。它们被广泛应用于各种问题中,如括 ...

C语言怎么调用API,这里的API是什么,有哪些常用功能
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-15 21:30:57 | 显示全部楼层
2985675302 发表于 2023-12-15 21:30
C语言怎么调用API,这里的API是什么,有哪些常用功能

在C语言中,调用API(Application Programming Interface)是通过使用外部库或操作系统提供的功能来实现特定功能。API提供了一组函数、数据结构和变量,允许程序与外部环境进行交互。

常见的API包括:

1. 标准C库API:C标准库提供了很多常用函数,如输入输出、字符串处理、数学计算等。可以通过包含相应的头文件(如stdio.h、string.h)并调用库函数来使用这些功能。

2. 操作系统API:操作系统提供了丰富的API,允许程序与操作系统进行交互。例如,Windows API(WinAPI)用于开发Windows应用程序,可以实现窗口管理、文件操作、进程管理等功能。而Linux提供的POSIX API(Portable Operating System Interface)则用于开发可移植的UNIX-like系统上的应用程序。

3. 第三方库API:第三方库是由其他组织或个人开发的库,提供了各种功能和算法。常见的第三方库包括图形库(如OpenGL、SDL)、网络库(如libcurl)、加密库(如OpenSSL)。要使用第三方库的API,需要将库文件链接到你的程序中,并包含相应的头文件。

4. 硬件API:如果你希望与硬件设备进行交互,可能需要使用特定的硬件API。例如,串口通信、GPIO控制等操作都需要使用硬件API来实现。

在调用API时,需要了解API的文档和函数签名(包括参数和返回值),以便正确地使用它们。通常,API会提供示例代码和详细的说明,帮助你理解和使用API。

要调用API,一般的步骤是:1)包含相应的头文件;2)根据API的要求,创建相应的数据结构或变量;3)调用API提供的函数;4)处理函数的返回值或结果。
以下是一个简单的示例,展示如何调用C标准库的API来打印字符串:
  1. #include <stdio.h>
  2. int main() {
  3.     char str[] = "Hello, World!";
  4.     printf("%s\n", str);
  5.     return 0;
  6. }
复制代码

在这个示例中,我们包含了<stdio.h>头文件,并使用了标准库的printf函数来打印字符串。通过调用API函数,我们可以实现打印输出的功能。
希望这个简单的例子能够帮助你更好地理解和开始使用API。记得多查阅文档和示例代码,不断练习和实践,以提高对API的理解和应用能力。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-10 02:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表