极简数据结构与算法学习心得

这篇博客详细介绍了四种经典的排序算法——选择排序、插入排序、归并排序和快速排序,包括它们的时间复杂度和实现过程。此外,还探讨了链表的基本操作,如遍历、插入、删除等。这些内容对于理解数据结构和算法优化至关重要。
摘要由CSDN通过智能技术生成

选择排序

void selectionSort(int a[], int N) {
  for (int L = 0; L <= N-2; L++) { // O(N)
    找到[L,N-1]区间的最小的数的序号X // O(N)
    swap(X, L) // O(1), 注意X可能等于L(没有交换)
  }
}

插入排序

void insertionSort(int a[], int N) { //插入排序
  for (int i = 1; i < N; i++) { // O(N)
    X = a[i]; // X 是要被插入的那个数
    for (j = i-1; j >= 0 && a[j] > X; j--) // 速度有快有慢
      a[j+1] = a[j]; // 为 X 腾出一个空间
    a[j+1] = X; // 此处为插入点
  }
}

归并排序

void merge(int a[], int low, int mid, int high) {
  // subarray1 = a[low..mid], subarray2 = a[mid+1..high], both sorted
  int N = high-low+1;
  int b[N]; // 讨论: 为什么我们需要一个临时的数组 b?
  int left = low, right = mid+1, bIdx = 0;
  while (left <= mid && right <= high) // 归并
    b[bIdx++] = (a[left] <= a[right]) ? a[left++] : a[right++];
  while (left <= mid) b[bIdx++] = a[left++]; // leftover, if any
  while (right <= high) b[bIdx++] = a[right++]; // leftover, if any
  for (int k = 0; k < N; k++) a[low+k] = b[k]; // copy back
}
void mergeSort(int a[], int low, int high) {
  // 要排序的数组是 a[low..high]
  if (low < high) { // 基础情况: low >= high (0或1项)
    int mid = (low+high) / 2;	
    mergeSort(a, low  , mid ); // 分成两半
    mergeSort(a, mid+1, high); // 递归地将它们排序
    merge(a, low, mid, high); // 解决步骤: 归并子程序
  }
}

快速排序

int partition(int a[], int i, int j) {
  int p = a[i]; // p 是 pivot
  int m = i; // S1 和 S2 一开始是空的
  for (int k = i+1; k <= j; k++) { // 探索未知的区域
    if (a[k] < p) { // case 2
      m++;
      swap(a[k], a[m]); // C++ STL algorithm std::swap
    } // 注意:在情况1的时候我们什么都不做: a[k] >= p
  }
  swap(a[i], a[m]); // 最后一步, 用a[m]交换 pivot
  return m; // 返回pivot的索引, 用于快速排序(Quick Sort)
}
void quickSort(int a[], int low, int high) {
  if (low < high) {
    int m = partition(a, low, high); // O(N)
    // a[low..high] ~> a[low..m–1], pivot, a[m+1..high]
    quickSort(a, low, m-1); // 递归地将左侧子数列排序
    // a[m] = pivot 在分区后就被排序好了
    quickSort(a, m+1, high); // 然后将右侧子数列排序
  }
}

链表遍历

Vertex* Get(int i) { // 返回顶点
  Vertex* ptr = head; // 我们必须从头开始
  for (int k = 0; k < i; ++k) // 向前推进 i 次
    ptr = ptr->next; // 指针指向更高的索引
  return ptr; 
}

插入

头部

Vertex* vtx = new Vertex(); // create new vertex vtx from item v
vtx->item = v;
vtx->next = head; // link this new vertex to the (old) head vertex
head = vtx; // the new vertex becomes the new head

中间

Vertex* pre = Get(i-1);/ /遍历到第(i-1)个节点,O(n)
aft = pre.next//aft不能为null

Vertex vtx = new Vertex(); // 创建新节点

vtx->item = v;

vtx->next = aft; //vtx的下一个指针设置为aft

pre->next = vtx; // pre的下一个指针设置为vtx

尾部插入

Vertex* vtx = new Vertex(); // C++
vtx->item = v; // 用 v 创建一个新的节点 vtx
tail->next = vtx; // 把尾部和 vtx 连起来
tail = vtx; // 现在更新尾部指针

头部删除

if (head == NULL) return; // 避免当SLL为空时崩溃

Vertex* temp = head; // 之后我们可以删除它

head = head->next; // 更新头部指针

delete temp; // 删除旧指针

删除中间

Vertex* pre = Get(i-1);/ /遍历到第(i-1)节点,O(n)
Vertex* del = pre->next, aft = del->next;

pre->next = aft; // 忽略del

delete del;

删除尾部

Vertex* pre = head;
temp = head->next;
while (temp->next != null) // 当下一个指针不是空
  pre = pre->next, temp = temp->next;
pre->next = null; // 或者 pre = Get(N-2), temp = Get(N-1)
delete temp; // temp = 旧的尾部指针
tail = pre; // 更新尾部指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撸码的xiao摩羯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值