设计算法,对于一个带头结点的整数单链表,以第1个结点为基准,将所有小于其值的结点移动到它的前面,将所有大于等于其值的结点移动到它的后面。
时间: 2023-09-04 09:05:22 浏览: 157
3-2 试编写一个算法,在带表头结点的单链表中寻找第i个结点.doc
### 回答1:
1. 定义三个指针:pre指向小于基准值的最后一个结点(初始为头结点),cur指向当前遍历的结点,next指向cur的下一个结点。
2. 遍历整个链表,如果cur的值小于基准值,则将cur插入到pre之后,同时更新pre的位置;否则继续遍历。
3. 遍历完成后,将基准值结点插入到pre之后,链表就按照要求分成了两部分。
代码如下:
```
void partition(ListNode* head) {
if (head == nullptr || head->next == nullptr) return;
int pivot = head->val; // 基准值
ListNode* pre = head;
ListNode* cur = head->next;
while (cur != nullptr) {
ListNode* next = cur->next;
if (cur->val < pivot) {
cur->next = pre->next;
pre->next = cur;
pre = cur;
} else {
pre = pre->next;
}
cur = next;
}
// 将基准值插入到pre之后
ListNode* pivot_node = new ListNode(pivot);
pivot_node->next = pre->next;
pre->next = pivot_node;
}
```
### 回答2:
设计算法如下:
1. 初始化三个指针,分别为smallerHead用于指向小于基准值的链表的头节点,smallerTail用于指向小于基准值的链表的尾节点,cur用于遍历链表。
2. 遍历链表,将小于基准值的节点移动到smaller链表中。具体操作如下:
- 如果cur指向的节点的值小于基准值:
* 如果smallerHead为空,则将smallerHead指向当前节点,smallerTail也指向当前节点。
* 如果smallerHead不为空,则将smallerTail的下一个节点设为当前节点,更新smallerTail指针。
- 移动cur指针到下一个节点。
3. 初始化两个指针,biggerHead用于指向大于等于基准值的链表的头节点,biggerTail用于指向大于等于基准值的链表的尾节点。
4. 继续遍历链表,将大于等于基准值的节点移动到bigger链表中。具体操作如下:
- 如果cur指向的节点的值大于等于基准值:
* 如果biggerHead为空,则将biggerHead指向当前节点,biggerTail也指向当前节点。
* 如果biggerHead不为空,则将biggerTail的下一个节点设为当前节点,更新biggerTail指针。
- 移动cur指针到下一个节点。
5. 将smallerTail和biggerHead连接起来,即将小于基准值的链表尾节点的下一个节点指向大于等于基准值的链表的头节点。
6. 如果smallerHead为空,则说明链表中没有小于基准值的节点,直接返回biggerHead作为排好序的链表的头节点;否则,返回smallerHead作为排好序的链表的头节点。
### 回答3:
设计算法如下:
1. 创建两个指针before和after,初始时都指向头结点。
2. 遍历链表,比较每个结点的值与基准值的大小关系:
a. 如果结点的值小于基准值,则将该结点移到前面,即将该结点的next指针指向before上一个结点,再将before指向该结点。
b. 如果结点的值大于等于基准值,则继续遍历下一个结点。
3. 遍历完毕后,将after指针指向最后一个小于基准值的结点的next指针,即所有大于等于基准值的结点跳过了。
4. 将before指针指向第一个结点的前一个结点,即头结点的前一个结点。
5. 如果存在小于基准值的结点,则before的next指针指向第一个小于基准值的结点;否则,before的next指针指向基准值结点。
6. 将基准值结点的next指针指向after即可完成整个链表的重新排列。
算法的时间复杂度为O(n),其中n是链表的长度。
阅读全文