quick sort
Time complexity = O ( nlogn ) O(nlogn)O(nlogn)
algorithm thinking
~~~~ Quick sort adopts the idea of divide and conquer, which divides the problem into multiple parts for solution.
The basic idea
- 1. First take a number from the sequence as the base number.
- 2. In the partitioning process, all the numbers larger than this number are placed on the right side of it, and all the numbers less than or equal to it are placed on the left side of it.
- 3. Then repeat the second step for the left and right intervals until each interval has only one number.
C language code to implement quick sort
#include <stdio.h>
#include <stdlib.h>
void quickSort(int* arr, int start, int end);
int main(void) {
int arr[] = {
12,555,41,0,5,3,96,21,8,3,555,20,60 };
int len = 13;
quickSort(arr, 0, 12);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
}
void quickSort(int* arr, int start, int end)
{
if (start >= end)
return;
int i = start, j = end;
int temp = arr[start];
printf("\nthis is a function");
while (i < j)
{
while (j > i && arr[j] > temp)
j--;
arr[i] = arr[j];
while (i < j && arr[i] < temp)
i++;
arr[j] = arr[i];
j--;
}
arr[i] = temp;
quickSort(arr, start, i-1);
quickSort(arr, i+1, end);
}
Assembly implementation
#基于汇编语言实现快速排序算法
.data
array: .word 2,1,3,55,0,6,9,22,84
len: .word 8
space: .asciiz " "
.globl main
.text
main:
move $a0,$zero
lw $a1,len
jal quickSort
li $t1,0 #设置t1为0
lw $t2,len#设置t2的值为len
sll $t2,$t2,2
print_array:
lw $a0,array+0($t1) #加载t1地址所储存的值
li $v0,1 # 设置系统调用指令
syscall
la $a0,space #打印空白间隔
li $v0,4
syscall
addi $t1,$t1,4 #指令加4
bgt $t1,$t2,Done #打印结束结束程序
j print_array
quickSort: #void quickSort(int* arr, int start,int end) 这里将arr做全局变量
addi $sp,$sp,-16 #创建栈帧储存returnAdress
sw $ra,0($sp) #将调用quickSort函数的返回地址储存在栈帧顶部
sw $a0,4($sp) #将start 储存在栈帧中
sw $a1,8($sp) #将end 储存在栈帧中
bge $a0,$a1,return #if start>=end return
move $t0,$a0 #int i = startIndex
move $t1,$a1#int j = endIndex
sll $t0,$t0,2 # i = 4*i
sll $t1,$t1,2 # j = 4*j
lw $t2,array + 0($t0) #temp = array[i] i 为索引
# while loop
whileLoop:
bge $t0,$t1,breakLoop #if i >= j goto outside loop
while1:
ble $t1,$t0,out1 #if j<= i break
lw $t3,array+0($t1) #temp2 = array[j]
ble $t3,$t2,out1 # if array[j]<=temp break
addi $t1,$t1,-4 # j-=4,在索引上j-=1
j while1
out1:
sw $t3,array+0($t0) #array[i] = array[j]
while2:
bge $t0,$t1,out2 #if i>=j break
lw $t3,array+0($t0) #temp2 = array[i]
bge $t3,$t2,out2 #if arrat[i]>=temp break
addi $t0,$t0,4 #i+=1
j while2
out2:
sw $t3,array+0($t1) #array[j] = array[i]
addi $t1,$t1,-4 #j- -
j whileLoop
breakLoop:
sw $t2,array+0($t0) #array[i] = temp
#调用函数1
#将索引还原为int指针
srl $t0,$t0,2
srl $a0,$a0,2
sw $t0,12($sp) #将i作为现场信息储存在栈帧中
addi $t0,$t0,-1
move $a1,$t0 #将第二个参数赋值为i-1
jal quickSort #quick(start,i-1)
#恢复现场信息
lw $a1,8($sp) #恢复end
lw $t0,12($sp) #恢复i
#调用函数2
addi $t0,$t0,1 #i+=1
move $a0,$t0 #将第一个参数赋值为i+1
jal quickSort
return:
lw $ra 0($sp)#在栈顶取返回地址
addi $sp,$sp,16#将栈执政上移一个栈帧
jr $ra
#return
Done:
Summarize
~~~~~ Quick sort alternately transforms the value of the pointer position by double pointers, finds a correct position for a number, and distributes the idea to each small part through the divide-and-conquer strategy.
Points to note
~~~~~ When implementing, care should be taken that only the pointers that move later are forced to move after swapping values.
- ~~~~~ If there is no forced movement, the program will enter an infinite loop.
- ~~~~~ Performing two forced moves will make the program inaccurate, that is, the i pointer may be behind the j pointer.