目录
1、简述
表插入排序(Table Insertion Sort)是一种基于插入排序的排序算法,它通过维护一个已排序的索引表来加速插入操作。在标准插入排序中,每次插入一个新元素时,需要在已排序数组中找到合适的位置并进行元素移动。而在表插入排序中,通过构建一个索引表,可以直接找到元素应该插入的位置,从而减少实际元素移动的次数。
实现步骤:
- 初 始化索引表:创建一个与待排序数组等长的索引表,初始时将索引按自然顺序(0, 1, 2, ..., n-1)排列。
- 构建索引表:
- 从待排序数组的第二个元素开始,依次将每个元素插入到已排序的索引表中。
- 找到当前元素在已排序索引表中的正确位置,并将索引插入。
- 调整索引表:插入新元素时,调整索引表中后续元素的位置以保持有序。
- 根据索引表重 排数组:根据排序后的索引表重新排列原数组中的元素。
2、复杂程度
- 时间复杂度:
- 平均时间复杂度:O(n^2),因为在插入每个元素时,可能需要扫描已排序部分的所有元素来找到插入位置。
- 最坏时间复杂度:O(n^2),当数组是逆序时,插入每个元素都需要移动前面所有的元素。
- 最好时间复杂度:O(n),当数组已经有序时,只需要进行一次线性扫描。
- 空间复杂度:
- O(n),需要额外的空间来存储索引表。
3、稳定性
表插入排序是一种稳定的排序算法,因为在插入元素时,即使有相等的元素,索引表中的顺序也能保证其相对位置不变。
4、实例
#include <iostream>
#include <vector>
// 链表节点类
struct ListNode {
int index;
ListNode* next;
ListNode(int idx) : index(idx), next(nullptr) {}
};
// 链表类
class LinkedList {
public:
LinkedList() : head(nullptr) {}
// 在链表中按顺序插入新的索引
void insertSorted(int index, const std::vector<int>& arr) {
ListNode* newNode = new ListNode(index);
if (!head || arr[head->index] >= arr[index]) {
newNode->next = head;
head = newNode;
} else {
ListNode* current = head;
while (current->next && arr[current->next->index] < arr[index]) {
current = current->next;
}
newNode->next = current->next;
current->next = newNode;
}
}
// 返回链表头指针
ListNode* getHead() const {
return head;
}
private:
ListNode* head;
};
// 表插入排序函数
std::vector<int> tableInsertionSort(const std::vector<int>& arr) {
int n = arr.size();
LinkedList sortedList;
// 将每个元素索引插入到链表中
for (int i = 0; i < n; ++i) {
sortedList.insertSorted(i, arr);
}
// 根据排序后的链表重排数组
std::vector<int> sortedArr;
ListNode* current = sortedList.getHead();
while (current) {
sortedArr.push_back(arr[current->index]);
current = current->next;
}
return sortedArr;
}
// 测试代码
int main() {
std::vector<int> array = {3, 1, 4, 1, 5, 9, 2, 6, 5};
std::vector<int> sortedArray = tableInsertionSort(array);
for (int num : sortedArray) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
快捷跳转:
生命不息,学习不止,若有不正确的地方,欢迎指正。