``` struct QSortStack {
public int high;
public int low;
}```
`     QSortStack* stack = stackalloc QSortStack [];`
```     unsafe static void qsort<T, U> (T[] keys, U[] items, int low0, int high0) where T : IComparable<T>
{
QSortStack* stack = stackalloc QSortStack [];
const int QSORT_THRESHOLD = ;
int high, low, mid, i, k;
int sp = ;
T key;

// initialize our stack
stack[].high = high0;
stack[].low = low0;

do {
// pop the stack
sp--;
high = stack[sp].high;
low = stack[sp].low;

if ((low + QSORT_THRESHOLD) > high) {
// switch to insertion sort
for (i = low + ; i <= high; i++) {
for (k = i; k > low; k--) {
// if keys[k] >= keys[k-1], break
if (keys[k-] == null)
break;

if (keys[k] != null && keys[k].CompareTo (keys[k-]) >= )
break;

swap (keys, items, k - , k);
}
}

continue;
}

// calculate the middle element
mid = low + ((high - low) / );

// once we re-order the lo, mid, and hi elements to be in
// ascending order, we'll use mid as our pivot.
QSortArrange<T, U> (keys, items, low, mid);
if (QSortArrange<T, U> (keys, items, mid, high))
QSortArrange<T, U> (keys, items, low, mid);

key = keys[mid];

// since we've already guaranteed that lo <= mid and mid <= hi,
// we can skip comparing them again
k = high - ;
i = low + ;

do {
if (key != null) {
// find the first element with a value >= pivot value
while (i < k && key.CompareTo (keys[i]) > )
i++;

// find the last element with a value <= pivot value
while (k > i && key.CompareTo (keys[k]) < )
k--;
} else {
while (i < k && keys[i] == null)
i++;

while (k > i && keys[k] != null)
k--;
}

if (k <= i)
break;

swap (keys, items, i, k);

i++;
k--;
} while (true);

// push our partitions onto the stack, largest first
// (to make sure we don't run out of stack space)
if ((high - k) >= (k - low)) {
if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}

if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}
} else {
if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}

if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}
}
} while (sp > );
}

// Specialized version for items==null
unsafe static void qsort<T> (T[] keys, int low0, int high0) where T : IComparable<T>
{
QSortStack* stack = stackalloc QSortStack [];
const int QSORT_THRESHOLD = ;
int high, low, mid, i, k;
int sp = ;
T key;

// initialize our stack
stack[].high = high0;
stack[].low = low0;

do {
// pop the stack
sp--;
high = stack[sp].high;
low = stack[sp].low;

if ((low + QSORT_THRESHOLD) > high) {
// switch to insertion sort
for (i = low + ; i <= high; i++) {
for (k = i; k > low; k--) {
// if keys[k] >= keys[k-1], break
if (keys[k-] == null)
break;

if (keys[k] != null && keys[k].CompareTo (keys[k-]) >= )
break;

swap (keys, k - , k);
}
}

continue;
}

// calculate the middle element
mid = low + ((high - low) / );

// once we re-order the lo, mid, and hi elements to be in
// ascending order, we'll use mid as our pivot.
QSortArrange<T> (keys, low, mid);
if (QSortArrange<T> (keys, mid, high))
QSortArrange<T> (keys, low, mid);

key = keys[mid];

// since we've already guaranteed that lo <= mid and mid <= hi,
// we can skip comparing them again
k = high - ;
i = low + ;

do {
if (key != null) {
// find the first element with a value >= pivot value
while (i < k && key.CompareTo (keys[i]) > )
i++;

// find the last element with a value <= pivot value
while (k >= i && key.CompareTo (keys[k]) < )
k--;
} else {
while (i < k && keys[i] == null)
i++;

while (k >= i && keys[k] != null)
k--;
}

if (k <= i)
break;

swap (keys, i, k);

i++;
k--;
} while (true);

// push our partitions onto the stack, largest first
// (to make sure we don't run out of stack space)
if ((high - k) >= (k - low)) {
if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}

if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}
} else {
if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}

if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}
}
} while (sp > );
}

static bool QSortArrange<K, V> (K [] keys, V [] items, int lo, int hi, IComparer<K> comparer)
{
IComparable<K> gcmp;
IComparable cmp;

if (comparer != null) {
if (comparer.Compare (keys[hi], keys[lo]) < ) {
swap<K, V> (keys, items, lo, hi);
return true;
}
} else if (keys[lo] != null) {
if (keys[hi] == null) {
swap<K, V> (keys, items, lo, hi);
return true;
}

gcmp = keys[hi] as IComparable<K>;
if (gcmp != null) {
if (gcmp.CompareTo (keys[lo]) < ) {
swap<K, V> (keys, items, lo, hi);
return true;
}

return false;
}

cmp = keys[hi] as IComparable;
if (cmp != null) {
if (cmp.CompareTo (keys[lo]) < ) {
swap<K, V> (keys, items, lo, hi);
return true;
}

return false;
}
}

return false;
}

// Specialized version for items==null
static bool QSortArrange<K> (K [] keys, int lo, int hi, IComparer<K> comparer)
{
IComparable<K> gcmp;
IComparable cmp;

if (comparer != null) {
if (comparer.Compare (keys[hi], keys[lo]) < ) {
swap<K> (keys, lo, hi);
return true;
}
} else if (keys[lo] != null) {
if (keys[hi] == null) {
swap<K> (keys, lo, hi);
return true;
}

gcmp = keys[hi] as IComparable<K>;
if (gcmp != null) {
if (gcmp.CompareTo (keys[lo]) < ) {
swap<K> (keys, lo, hi);
return true;
}

return false;
}

cmp = keys[hi] as IComparable;
if (cmp != null) {
if (cmp.CompareTo (keys[lo]) < ) {
swap<K> (keys, lo, hi);
return true;
}

return false;
}
}

return false;
}

unsafe static void qsort<K, V> (K [] keys, V [] items, int low0, int high0, IComparer<K> comparer)
{
QSortStack* stack = stackalloc QSortStack [];
const int QSORT_THRESHOLD = ;
int high, low, mid, i, k;
IComparable<K> gcmp;
IComparable cmp;
int sp = ;
K key;

// initialize our stack
stack[].high = high0;
stack[].low = low0;

do {
// pop the stack
sp--;
high = stack[sp].high;
low = stack[sp].low;

if ((low + QSORT_THRESHOLD) > high) {
// switch to insertion sort
for (i = low + ; i <= high; i++) {
for (k = i; k > low; k--) {
// if keys[k] >= keys[k-1], break
if (comparer != null) {
if (comparer.Compare (keys[k], keys[k-]) >= )
break;
} else {
if (keys[k-] == null)
break;

if (keys[k] != null) {
gcmp = keys[k] as IComparable<K>;
cmp = keys[k] as IComparable;
if (gcmp != null) {
if (gcmp.CompareTo (keys[k-]) >= )
break;
} else {
if (cmp.CompareTo (keys[k-]) >= )
break;
}
}
}

swap<K, V> (keys, items, k - , k);
}
}

continue;
}

// calculate the middle element
mid = low + ((high - low) / );

// once we re-order the low, mid, and high elements to be in
// ascending order, we'll use mid as our pivot.
QSortArrange<K, V> (keys, items, low, mid, comparer);
if (QSortArrange<K, V> (keys, items, mid, high, comparer))
QSortArrange<K, V> (keys, items, low, mid, comparer);

key = keys[mid];
gcmp = key as IComparable<K>;
cmp = key as IComparable;

// since we've already guaranteed that lo <= mid and mid <= hi,
// we can skip comparing them again.
k = high - ;
i = low + ;

do {
// Move the walls in
if (comparer != null) {
// find the first element with a value >= pivot value
while (i < k && comparer.Compare (key, keys[i]) > )
i++;

// find the last element with a value <= pivot value
while (k > i && comparer.Compare (key, keys[k]) < )
k--;
} else {
if (gcmp != null) {
// find the first element with a value >= pivot value
while (i < k && gcmp.CompareTo (keys[i]) > )
i++;

// find the last element with a value <= pivot value
while (k > i && gcmp.CompareTo (keys[k]) < )
k--;
} else if (cmp != null) {
// find the first element with a value >= pivot value
while (i < k && cmp.CompareTo (keys[i]) > )
i++;

// find the last element with a value <= pivot value
while (k > i && cmp.CompareTo (keys[k]) < )
k--;
} else {
while (i < k && keys[i] == null)
i++;

while (k > i && keys[k] != null)
k--;
}
}

if (k <= i)
break;

swap<K, V> (keys, items, i, k);

i++;
k--;
} while (true);

// push our partitions onto the stack, largest first
// (to make sure we don't run out of stack space)
if ((high - k) >= (k - low)) {
if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}

if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}
} else {
if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}

if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}
}
} while (sp > );
}

// Specialized version for items==null
unsafe static void qsort<K> (K [] keys, int low0, int high0, IComparer<K> comparer)
{
QSortStack* stack = stackalloc QSortStack [];
const int QSORT_THRESHOLD = ;
int high, low, mid, i, k;
IComparable<K> gcmp;
IComparable cmp;
int sp = ;
K key;

// initialize our stack
stack[].high = high0;
stack[].low = low0;

do {
// pop the stack
sp--;
high = stack[sp].high;
low = stack[sp].low;

if ((low + QSORT_THRESHOLD) > high) {
// switch to insertion sort
for (i = low + ; i <= high; i++) {
for (k = i; k > low; k--) {
// if keys[k] >= keys[k-1], break
if (comparer != null) {
if (comparer.Compare (keys[k], keys[k-]) >= )
break;
} else {
if (keys[k-] == null)
break;

if (keys[k] != null) {
gcmp = keys[k] as IComparable<K>;
cmp = keys[k] as IComparable;
if (gcmp != null) {
if (gcmp.CompareTo (keys[k-]) >= )
break;
} else {
if (cmp.CompareTo (keys[k-]) >= )
break;
}
}
}

swap<K> (keys, k - , k);
}
}

continue;
}

// calculate the middle element
mid = low + ((high - low) / );

// once we re-order the low, mid, and high elements to be in
// ascending order, we'll use mid as our pivot.
QSortArrange<K> (keys, low, mid, comparer);
if (QSortArrange<K> (keys, mid, high, comparer))
QSortArrange<K> (keys, low, mid, comparer);

key = keys[mid];
gcmp = key as IComparable<K>;
cmp = key as IComparable;

// since we've already guaranteed that lo <= mid and mid <= hi,
// we can skip comparing them again.
k = high - ;
i = low + ;

do {
// Move the walls in
if (comparer != null) {
// find the first element with a value >= pivot value
while (i < k && comparer.Compare (key, keys[i]) > )
i++;

// find the last element with a value <= pivot value
while (k > i && comparer.Compare (key, keys[k]) < )
k--;
} else {
if (gcmp != null) {
// find the first element with a value >= pivot value
while (i < k && gcmp.CompareTo (keys[i]) > )
i++;

// find the last element with a value <= pivot value
while (k > i && gcmp.CompareTo (keys[k]) < )
k--;
} else if (cmp != null) {
// find the first element with a value >= pivot value
while (i < k && cmp.CompareTo (keys[i]) > )
i++;

// find the last element with a value <= pivot value
while (k > i && cmp.CompareTo (keys[k]) < )
k--;
} else {
while (i < k && keys[i] == null)
i++;

while (k > i && keys[k] != null)
k--;
}
}

if (k <= i)
break;

swap<K> (keys, i, k);

i++;
k--;
} while (true);

// push our partitions onto the stack, largest first
// (to make sure we don't run out of stack space)
if ((high - k) >= (k - low)) {
if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}

if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}
} else {
if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}

if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}
}
} while (sp > );
}

static bool QSortArrange<T> (T [] array, int lo, int hi, Comparison<T> compare)
{
if (array[lo] != null) {
if (array[hi] == null || compare (array[hi], array[lo]) < ) {
swap<T> (array, lo, hi);
return true;
}
}

return false;
}

unsafe static void qsort<T> (T [] array, int low0, int high0, Comparison<T> compare)
{
QSortStack* stack = stackalloc QSortStack [];
const int QSORT_THRESHOLD = ;
int high, low, mid, i, k;
int sp = ;
T key;

// initialize our stack
stack[].high = high0;
stack[].low = low0;

do {
// pop the stack
sp--;
high = stack[sp].high;
low = stack[sp].low;

if ((low + QSORT_THRESHOLD) > high) {
// switch to insertion sort
for (i = low + ; i <= high; i++) {
for (k = i; k > low; k--) {
if (compare (array[k], array[k-]) >= )
break;

swap<T> (array, k - , k);
}
}

continue;
}

// calculate the middle element
mid = low + ((high - low) / );

// once we re-order the lo, mid, and hi elements to be in
// ascending order, we'll use mid as our pivot.
QSortArrange<T> (array, low, mid, compare);
if (QSortArrange<T> (array, mid, high, compare))
QSortArrange<T> (array, low, mid, compare);

key = array[mid];

// since we've already guaranteed that lo <= mid and mid <= hi,
// we can skip comparing them again
k = high - ;
i = low + ;

do {
// Move the walls in
if (key != null) {
// find the first element with a value >= pivot value
while (i < k && compare (key, array[i]) > )
i++;

// find the last element with a value <= pivot value
while (k > i && compare (key, array[k]) < )
k--;
} else {
while (i < k && array[i] == null)
i++;

while (k > i && array[k] != null)
k--;
}

if (k <= i)
break;

swap<T> (array, i, k);

i++;
k--;
} while (true);

// push our partitions onto the stack, largest first
// (to make sure we don't run out of stack space)
if ((high - k) >= (k - low)) {
if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}

if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}
} else {
if ((k - ) > low) {
stack[sp].high = k;
stack[sp].low = low;
sp++;
}

if ((k + ) < high) {
stack[sp].high = high;
stack[sp].low = k;
sp++;
}
}
} while (sp > );
}```

## struct的更多相关文章

1. 使用struct处理二进制

有的时候需要用python处理二进制数据,比如,存取文件.socket操作时.这时候,可以使用python的struct模块来完成. struct模块中最重要的三个函数是pack(), unpack( ...

2. golang struct扩展函数参数命名警告

今天在使用VSCode编写golang代码时,定义一个struct,扩展几个方法,如下: package storage import ( "fmt" "github.c ...

3. go-使用 unsafe 修改 struct 中的 field 的值

以下是方法,不要纠结原理,等东西积累多了,你才有能力纠结原理: 首先,你需要有一个这样的函数,这是在 nsq 的源码里直接抄过来的: func unsafeValueOf(val reflect.Va ...

4. C语言中struct位域的定义和使用

位域的定义和使用 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又 ...

5. C# Struct结构体里数组长度的指定

typedef struct Point{ unsigned short x; unsigned short y; }mPoint;//点坐标 typedef struct Line{ mPoint ...

6. C 语言Struct 实现运行类型识别 RTTI

通过RTTI,能够通过基类的指针或引用来检索其所指对象的实际类型.c++通过下面两个操作符提供RTTI. (1)typeid:返回指针或引用所指对象的实际类型.    (2)dynamic_cast: ...

7. VC++ : error LNK2001: unresolved external symbol &quot;__declspec(dllimport) public: __thiscall std::basic_string&lt;wchar_t,struct std::char_traits&lt;wchar_t&gt;

8. 字节流与数据类型的相互转换---使用struct模块

字节流与数据类型的相互转换---使用struct模块 http://blog.csdn.net/Sunboy_2050/article/details/5974029 Python是一门非常简洁的语言 ...

9. 窥探Swift之别具一格的Struct和Class

说到结构体和类,还是那句话,只要是接触过编程的小伙伴们对这两者并不陌生.但在Swift中的Struct和Class也有着令人眼前一亮的特性.Struct的功能变得更为强大,Class变的更为灵活.St ...

10. struct 大小计算

结构体是一种复合数据类型,通常编译器会自动的进行其成员变量的对齐,已提高数据存取的效率.在默认情况下,编译器为结构体的成员按照自然对齐(natural alignment)条方式分配存储空间,各个成员 ...

## 随机推荐

1. chose.jquery 多选

<select id="language" data-placeholder="选择类别..." class="chosen-select&qu ...

2. java错题本

1.判断题: Java程序一般应当含有main方法,因为它是所有JaVa程序执行的入口(错) 解析:applet(java小程序)不用,application(java应用程序)需要.(见java a ...

3. JS中NULL和undifined区别及NULL的作用

1.博客地址:http://www.cnblogs.com/eastday/archive/2010/03/03/1677324.html 2.参考地址2:https://www.zhihu.com/ ...

4. MYSQL 命令行导入导出

1.导出mysql数据库 mysqldump -h[服务器地址本机可以忽略] -u[用户] -p[密码] -P[myql数据库端口]>导出文件位置 mysqldump -h192. -uroot ...

5. Linux 终端下颜色的输出

在命令行下也能产生五颜六色的字体和图案,只需要加上一些颜色代码,例如 echo -e "\033[41;36m 红底绿字\033[0m" 其中41的位置代表底色, 36的位置是代表 ...

6. php示例代码

11111<?php \$var = 'ABCDEFGH:/MNRPQR/'; echo "Original: \$var<hr />\n"; /* 这两个例子使用 ...

7. linux拷贝多个目录下的文件到同一个目录

拷贝a目录下的a.txt和b目录下的b.txt到c目录 cp -a \ /root/a/a.txt \ /root/b/b.txt \ /root/c/

8. 【剑指offer】不使用新变量，交换两个变量的值，C++实现

# 题目 不使用新变量,交换两个变量的值. # 思路 方法一:使用加减法操作,交换两个变量的值. A = A+B B = A-B A = A-B 方法二:使用异或运算,交换两个变量的值 A = A^B ...

9. Linux 监视文件、文件夹改动

/******************************************************************** * Linux 监视文件.文件夹改动 * 说明: * 主要是 ...

10. 清北刷题冲刺 11-03 a.m

纸牌 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...