C语言记录
快速开始
main()
1 2 3 4 5 6 7
| #include<stdio.h> #include <stdlib.h>
int main() { system("pause"); return 0; }
|
选择菜单栏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| while (true) { ListMenu(); printf("请输入您的选择:\n"); int choice = intCin(); switch (choice) { case 0: ExitSystem(); break; case 1: { system("pause"); system("cls"); } break; case 2: { system("pause"); system("cls"); } break; case 3: { system("pause"); system("cls"); } break; default: printf("非法输入,请重新输入!\n"); system("pause"); system("cls"); break; } }
|
1 2 3 4 5 6 7 8 9
| void ListMenu() { printf("*******************************************\n"); printf("**************菜单*************************\n"); printf("**************0.退出***********************\n"); printf("**************1.**************************\n"); printf("**************2.***************************\n"); printf("**************3.***************************\n"); printf("**************10.*************************\n"); }
|
1 2 3 4 5 6
| void ExitSystem() { printf("欢迎下次使用!\n"); system("pause"); exit(0); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| int intCin() { int num; while (true) { printf("等待输入中 ……\n"); printf("\n"); if (scanf_s("%d", &num) != 1) { while (getchar() != '\n') continue; printf("输入格式错误(输入的不是整数)!请重新输入:\n"); continue; } return num; } }
|
格式化输出字符
%d
:有符号十进制整数,用于格式化输出 int
, long
, short
等有符号整型变量。
%u
:无符号十进制整数,用于格式化输出 unsigned int
, unsigned long
, unsigned short
等无符号整型变量。
%f
:浮点数,用于格式化输出 float
和 double
类型的浮点数。
%c
:字符,用于格式化输出 char
类型的变量或表达式。
%s
:字符串,用于格式化输出字符串。
除此之外,还有一些用于格式化输出指针地址、长整型、短整型等类型的格式化输出字符。
%p
:指针地址,格式化输出 void
* 指针类型变量或表达式的地址。
%ld
或 %li:长整形有符号十进制整数,用于格式化输出 long
类型的变量。
%lu
:长整形无符号十进制整数,用于格式化输出 unsigned long
类型的变量。
%hd
或 %hi
:短整形有符号十进制整数,用于格式化输出 short
类型的变量。
%hu
:短整形无符号十进制整数,用于格式化输出 unsigned short
类型的变量。
%i
是C语言中的格式化输出字符,用于以有符号十进制整数形式输出整型变量。
与 %d
格式化输出字符不同的是,%i
格式化输出字符可以根据数据前缀的不同来自动判断要转换的数据类型
- 如果数据前缀是
0x
或0X
,则按照十六进制有符号整数进行输出。
- 如果数据前缀是
0
,则会按照八进制有符号整数进行输出。
- 如果数据前缀是其他字符或者没有前缀,则按照十进制有符号整数进行输出。
1 2 3 4 5 6 7 8
| int x = 100; printf("%i\n", x);
int y = 0xA0; printf("%i\n", y);
int z = 0123; printf("%i\n", z);
|
结构体
在 C 语言中,结构体本身并不支持构造函数的概念,必须通过手动初始化结构体变量来赋值。
不过,可以通过一些技巧来实现类似构造函数的功能,可以使用结构体初始化器来对结构体成员进行初始化,在定义结构体时给每个成员提供默认值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| struct Person { char name[16]; int age; };
ElemType create_struct(const char* name, int age) { ElemType e = { "", 0 }; if (name != NULL) { strncpy_s(e.name, sizeof(e.name) ,name, sizeof(e.name)-1); } e.age = age; return e; }
|
函数
IO
scanf_s
是C语言中输入函数scanf的安全版本。
1
| int scanf_s(const char *format, ...)
|
1 2 3 4 5 6 7 8 9
| #include <stdio.h>
int main() { int num; printf("Enter a number: "); scanf_s("%d", &num, sizeof(num)); printf("You entered: %d\n", num); return 0; }
|
1 2
| char name[16]; scanf_s("s", name, sizeof(name));
|
1
| scanf_s("%15s", name, sizeof(name));
|
字符串
在 C 语言中,使用字符数组来表示字符串。字符串是由一系列字符组成的数据类型,以 null 字符(‘\0’) 结束
可以这样声明字符串1
| char str_array[数组大小][最大字符串长度] = {字符串1, 字符串2, ..., 字符串n};
|
strncpy_s()
是一个C标准库函数,用于将一个字符串的指定长度复制到另一个字符数组中。
1
| errno_t strncpy_s(char* dest, size_t destSize, const char* src, size_t count);
|
dest
表示目标字符串
destSize
表示目标字符串的长度
src
表示源字符串
count
表示要拷贝的字符数
和strcpy不同,strncpy_s会在拷贝过程中检查目标字符串的长度是否足够。如果目标字符串的长度(destSize)小于等于要拷贝的字符数(count),则会终止拷贝,并返回错误码(通过errno_t返回)。否则,将源字符串的前count个字符复制到目标字符串中,并在目标字符串的最后一位添加一个’\0’,以保证目标字符串的正确性。
由于strncpy_s
函数会强制在目标字符串末尾追加’\0’,因此在使用时需要保证目标字符串的长度(destSize)大于等于要拷贝的字符数(count)+1,以避免内存溢出等问题
1
| strncpy_s(e.name, sizeof(e.name) ,name, sizeof(e.name)-1);
|
strcmp()
是 C 标准库中的一个用于比较两个字符串是否相等的函数。定义在 string.h
头文件中
1
| int strcmp(const char *str1, const char *str2);
|
str1 和 str2 分别是两个要比较的字符串。该函数会从两个字符串的第一个字符开始逐个比较,直到遇到第一个不同的字符或者字符串的结尾。
如果两个字符串相等,则返回值为 0
;
如果 str1 小于 str2,则返回值为负数;
如果 str1 大于 str2,则返回值为正数。
内存管理
malloc()
是 C 语言中的标准库函数,用于动态分配内存空间。
1
| void* malloc(size_t size);
|
其中,size
表示需要分配的内存大小,单位为字节。该函数返回一个指向分配内存空间起始地址的指针,如果分配失败,则返回 NULL。
malloc()
函数申请的内存空间通常是在堆(heap)中分配的,而非在栈(stack)中分配。由于在使用完内存后需要显式地调用 free()
函数来释放空间,因此 malloc()
函数能够帮助程序员更灵活地管理内存空间,避免浪费和泄漏等问题。
1 2 3 4 5 6 7 8 9 10 11 12
| int n = 10; int* arr = (int*)malloc(sizeof(int) * n); if (arr == NULL) { printf("申请内存失败!\n"); return 1; }
for (int i = 0; i < n; i++) { arr[i] = 0; }
free(arr);
|
realloc()
是 C 语言中的标准库函数,用于重新分配内存空间
1
| void* realloc(void* ptr, size_t size);
|
ptr
表示原先已经分配的内存空间地址,size
表示需要重新分配的内存大小,单位为字节。该函数返回一个指向重新分配内存空间起始地址的指针,如果分配失败,则返回 NULL。
realloc()
函数的作用是在堆(heap)中重新分配内存空间,可以用于修改已经分配的内存大小和释放未使用的内存空间。当需要扩展或缩小内存空间时,realloc()
函数能够有效地避免浪费内存资源的问题。
在使用 realloc()
函数修改已经分配的内存大小时,需要确保原先已经分配的内存空间地址有效(即非空指针),同时也需要确保新的内存大小不小于 0。当 size
小于原先已经分配的内存大小时,realloc()
函数会将多余的部分从堆(heap)中释放掉,并返回一个指向已经缩小后的内存空间起始地址的指针。需要注意的是,在缩小内存空间时,如果原先已经分配的内存空间中仍有数据未被复制到新的内存空间中,这些数据可能会丢失。在重新分配内存时,realloc()
函数会自动将原先内存中的数据复制到新的内存空间中,并且返回新的指针供程序使用。在程序中使用完内存后,还需要调用 free()
函数来手动释放已经分配的内存空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| int n = 10; int* arr = (int*)malloc(sizeof(int) * n); if (arr == NULL) { printf("申请内存失败!\n"); return 1; }
int* newSpace = (int*)realloc(arr, sizeof(int) * n * 2); if (newSpace == NULL) { printf("申请新内存失败!\n"); free(arr); return 1; } else { arr = newSpace; n *= 2; }
for (int i = 0; i < n; i++) { arr[i] = i; }
free(arr);
|
memcpy()
函数的作用是将一个源内存地址的数据复制到目标内存地址
1
| void *memcpy(void *dest, const void *src, size_t n);
|
dest
:目标内存地址,即要拷贝到的地址。
src
:源内存地址,即要拷贝的地址。
n
:要拷贝的字节数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <stdio.h> #include <string.h>
int main() { char src[] = "Hello World!"; char dest[16]; size_t len = strlen(src) + 1; memcpy(dest, src, len);
printf("src = %s\n", src); printf("dest = %s\n", dest); return 0; }
|
free()
函数用于释放动态分配的内存空间,确保本次申请的内存空间不再使用,避免内存泄漏。
在程序中调用 free()
函数时,需要传入需要被释放掉的内存地址。该函数会释放该地址上的内存,并将其还给操作系统。只有使用 malloc()
、calloc()
或 realloc()
等动态内存分配函数分配的内存空间才需要使用 free()
函数进行释放,否则会导致程序异常或崩溃。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <stdio.h> #include <stdlib.h>
int main() { int *arr; int n = 10;
arr = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++) { arr[i] = i + 1; }
free(arr);
return 0; }
|
关于C的使用问题
size_t
size_t
是一种定义在 C 语言标准库 <stddef.h>
中的无符号整型数据类型,用于表示一个对象的大小或一个数组的元素个数。它的长度通常和 unsigned int
或 unsigned long
相同,但是具体长度取决于编译器和平台的实现。
在 C 语言程序中,我们通常使用 size_t
来避免在不同平台上出现不同的整型长度所带来的问题。例如,当我们需要动态分配内存时,往往会使用 malloc() 函数,而该函数接受一个参数,即需要分配的内存大小。这个大小通常使用 size_t
类型来表示,以确保程序在不同平台上的兼容性。
另外,一些标准库函数(如 strlen()
、sizeof()
等)也会返回 size_t
类型的值,表示对象的长度或大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <stdio.h> #include <stddef.h>
int main() { size_t size = sizeof(int); printf("size of int: %zu bytes\n", size);
char str[] = "Hello World!"; size_t len = strlen(str); printf("length of string: %zu\n", len);
return 0; }
|
数组越界访问
如下代码在C中是可以运行的(只会报警告)
1 2
| int arr[9] = { 0 }; printf("%d", arr[99]);
|
这段代码的输出结果是未定义行为(Undefined Behavior),意味着无法确定输出的结果会是什么。
在C/C++中,数组越界访问是一种未定义行为。在这里,数组arr只有9个元素,却试图访问它的第100个元素(即arr[99]),这超出了数组arr的边界,因此会导致未定义行为。
虽然在一些编译器和计算机架构上,这段代码可能不会引发任何错误,但是在其他情况下,它可能会导致程序崩溃或产生不可预测的结果。因此,应该尽量避免数组越界访问。
清空输入缓冲区
当使用 scanf_s
函数读取输入时,如果输入不符合格式要求【 scanf_s("%d", &num);
输入汉字】,scanf_s
会将非法字符从输入缓冲区中移除,但这可能会导致下一次输入不能正确进行。
为了解决这个问题,我们可以手动清空输入缓冲区,以确保下一次输入的准确性。
在输入错误时,我们先调用 getchar 函数逐个读取非法字符并将其丢弃,直到读取到换行符为止,以清空输入缓冲区。然后输出提示信息,终止程序执行。
1 2 3 4 5 6 7 8 9
| int num; int ret = scanf_s("%d", &num, sizeof(num)); if (ret != 1) { while(getchar() != '\n') continue; printf("输入错误!\n"); return -1; }
|
Coding
ElemType
在定义数据结构时,经常使用ElemType
是为了表示数据结构中存储的元素的类型。ElemType
通常是一个抽象的数据类型,可以根据实际情况来具体定义。
使用ElemType
的好处有以下几点:
- 灵活性:
ElemType
可以根据实际需要选择不同的数据类型,比如整数、浮点数、字符、结构体等。这样可以适应不同的数据结构和算法需求。
- 可读性:使用
ElemType
可以使代码更加易读和易理解,因为它提供了对存储元素类型的清晰描述。
- 可扩展性:通过定义
ElemType
,可以方便地扩展数据结构,以适应未来的需求变化。如果需要修改存储元素类型,只需修改ElemType
的定义,而不需要改动整个数据结构的代码。
- 代码复用性:使用
ElemType
可以提高代码的复用性,因为可以将同一类型的数据结构和算法应用于不同的ElemType
上。
定义一个结构体,构造好如下函数
- 定义一个比较函数,用于比较结构体,不等返回0,相等为真 (
__Compare
)
- 定义一个输出函数,用于输出结构体,有点像重写toString(
__Print
)
- 定义类似构造函数的函数(
create_struct
)
在 C 语言中,结构体本身并不支持构造函数的概念,必须通过手动初始化结构体变量来赋值
不过,可以通过一些技巧来实现类似构造函数的功能
比如定义一个Person
类
Person.hlink1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #pragma once #include<stdio.h> #include<string.h>
struct Person { char name[16]; int age; };
typedef Person ElemType;
int PersonCompare(ElemType e1, ElemType e2);
void PersonPrint(ElemType e);
ElemType create_struct(); ElemType create_struct(const char* name, int age);
|
Person.cpplink1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include"Person.h"
int PersonCompare(ElemType e1, ElemType e2) { return e1.age == e2.age && !strcmp(e1.name, e2.name); }
void PersonPrint(ElemType e) { printf("姓名:%s\t年龄:%d\n", e.name, e.age); }
ElemType create_struct() { ElemType e = { NULL, 0 }; return e; }
ElemType create_struct(const char* name, int age) { ElemType e = { "", 0 }; if (name != NULL) { strncpy_s(e.name, name, sizeof(e.name) - 1); } e.age = age; return e; }
|
定义自定义函数
myFunction.hlink1 2 3 4 5 6 7 8 9
| #pragma once #include<stdio.h> #include<stdlib.h>
void test();
int intCin();
void ExitSystem();
|
myFunction.cpplink1 2 3 4
| #include"myFunction.h" void test() { printf("This is a test statement\n"); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| int intCin() { int num; while (true) { printf("等待输入中 ……\n"); printf("\n"); if (scanf_s("%d", &num) != 1) { while (getchar() != '\n') continue; printf("输入格式错误(输入的不是整数)!请重新输入:\n"); continue; } return num; } }
|
1 2 3 4 5 6
| void ExitSystem() { printf("欢迎下次使用!\n"); system("pause"); exit(0); }
|
线性表
顺序表
线性表中元素的位序从1
开始的,而数组中的元素下标是从0
开始的!
顺序表(静态分配)
CodeOcean-sequentialList.h
CodeOcean-sequentialList.cpp
1 2 3 4 5 6 7
| #define MaxSize 50
typedef struct { ElemType data[MaxSize]; int length; }SqList;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| SqList InitList();
void ClearList(SqList& L);
void DestroyList(SqList& L);
bool ListEmpty(SqList L);
int ListLength(SqList L);
void GetElem(SqList L,int i,ElemType& e);
int LocateElem(SqList L, ElemType e, int(*myCompare)(ElemType, ElemType));
void ListInsert(SqList& L,int i, ElemType e);
void ListDelete(SqList& L, int i, ElemType& e);
void TraverseList(SqList L, void(*myPrint)(ElemType));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| SqList InitList() { SqList L; L.length = MaxSize; ClearList(L); return L; } void ClearList(SqList& L) { for (int i = 0; i < L.length; i++) { ElemType e = create_struct(); L.data[i] = e; } L.length = 0; }
|
1 2 3 4 5 6 7 8
| void GetElem(SqList L, int i, ElemType& e) { if (i<1 || i>L.length) { printf("位序不存在!,当前顺序表长度%d\n", L.length); return; } e = L.data[i-1]; }
|
1 2 3 4 5 6 7 8 9
| int LocateElem(SqList L, ElemType e, int(*myCompare)(ElemType, ElemType)) { for (int i = 0; i < L.length; i++) { if (myCompare(L.data[i],e)) { return i+1; } } return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void ListInsert(SqList& L, int i, ElemType e) { if (L.length == MaxSize) { printf("顺序表已满!无法完成插入操作!\n"); return; } if (i<1 || i>L.length + 1) { printf("位序不合法!,当前顺序表长度%d\n", L.length); return; } for (int j = L.length; j >= i; j--) { L.data[j] = L.data[j-1]; } L.data[i-1] = e; L.length += 1; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void ListDelete(SqList& L, int i, ElemType& e) { if (i>L.length || i < 1) { printf("这不是一个有效位置,顺序表当前长度:%d\n", L.length); return; } e = L.data[i-1]; while (i < L.length) { L.data[i-1] = L.data[i]; i++; } L.length --; printf("删除成功!删除信息如下:\n"); PersonPrint(e); }
|
顺序表(动态分配)
CodeOcean-DynamicSequentialList.h
CodeOcean-DynamicSequentialList.cpp
1 2 3 4 5 6 7 8
| #define InitSize 10
typedef struct { ElemType *data; int capacity; int length; }SeqList;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| SeqList InitList(SeqList& L);
void ClearList(SeqList& L);
void DestroyList(SeqList& L);
bool ListEmpty(SeqList L);
int ListLength(SeqList L);
bool GetElem(SeqList L, int i, ElemType& e);
int LocateElem(SeqList L, ElemType e, int(*myCompare)(ElemType, ElemType));
bool ListInsert(SeqList& L, int i,ElemType e);
bool ListDelete(SeqList& L, int i, ElemType& e);
void TraverseList(SeqList L,void(*myPrint)(ElemType));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| SeqList InitList(SeqList& L) { if (L.data!=NULL) { printf("顺序表表已初始化!无需二次初始!\n"); return L; } L.data = (ElemType*)malloc(sizeof(ElemType) * InitSize); if (L.data == NULL) { printf("内存申请失败!\n"); system("pause"); L = InitList(L); } L.length = 0; L.capacity = InitSize; return L; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| bool GetElem(SeqList L, int i, ElemType& e) { if (L.data == NULL) { errorInfo(); return false; } if (i<1 || i>L.length) { printf("查找位序应该在[1,%d+1],位置无效!\n", L.length); return false; } e = L.data[i - 1]; return true; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int LocateElem(SeqList L, ElemType e, int(*myCompare)(ElemType, ElemType)) { if (L.data == NULL) { errorInfo(); return 0; } for (int i = 0; i < L.length; i++) { if (myCompare(L.data[i],e)) { return i + 1; } } return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| void my_malloc(SeqList& L) { ElemType *newSpace=(ElemType*)malloc(sizeof(ElemType) * L.capacity*2); if (newSpace==NULL) { printf("顺序表已满,动态分配内存失败!插入失败!\n"); return; } memcpy(newSpace, L.data, sizeof(ElemType) * L.capacity); free(L.data); L.data = NULL; L.data = newSpace; L.capacity *= 2; printf("线性表已满,但是动态重新分配内存!\n"); } void re_alloc(SeqList& L) { ElemType* newSpace = (ElemType*)realloc(L.data, sizeof(ElemType) * L.capacity * 2); if (newSpace == NULL) { printf("线性表已满,但是动态内存分配失败!插入失败!\n"); return; } L.data = newSpace; L.capacity *= 2; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| bool ListInsert(SeqList& L,int i, ElemType e) { if (L.data == NULL) { errorInfo(); return false; } if (i<1 || i>L.length + 1) { printf("插入的位置应该在[1,%d+1],位置无效!\n",L.length); return false; } if (L.length==L.capacity) { my_malloc(L); } for (int j = L.length;j >= i; j--) { L.data[j] = L.data[j - 1]; } L.data[i - 1] = e; L.length++; return true; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| bool ListDelete(SeqList& L, int i, ElemType& e) { if (L.data == NULL) { errorInfo(); return false; } if (i<1 || i>L.length) { printf("删除的位置应该在[1,%d],位置无效!\n", L.length); return false; } e = L.data[i - 1]; for (int j = i; j < L.length; j++) { L.data[j - 1] = L.data[j]; } L.length--; return true; }
|
链表
CodeOcean-LinkList.h
CodeOcean-LinkList.cpp
1 2 3 4
| typedef struct LNode { ElemType data; LNode* next; }LNode,*LinkList;
|
- 这里定义的是单链表中每个节点的存储结构,包括数据域和指针域。
- 为提高程序的可读性,对同一结构体指针类型起了两个名称,
LinkList
与LinkList
,两者本质上是等价的。通常习惯上用LinkList
定义单链表,强调定义的是某个单链表的头指针;用LinkList
定义指向单链表中任意节点的指针变量。
- 单链表是由头指针唯一确定的,因此单链表可以用头指针的名字来命名。若头指针名是
L
,则简称链表为表L
。
- 注意区分指针变量和结点变量,若定义
LinkList p
或 LNode *p
,则p
为指向某结点的指针变量,表示该结点的地址;而*p
为对应的结点变量,表示该结点的名称。思考(*p).data
与*p->data
表示什么。
- 首元结点:链表中存储第一个数据元素
a1
的结点。
- 头结点:在首元结点之前附设的一个结点,其指针域指向首元结点。
- 头指针:链表中第一个结点的指针。若链表设有头结点,则头指针指向头结点;若链表不设头结点,则头指针所指结点为首元结点。
链表增加头结点的作用
- 便于首元结点的处理:增加了头结点后,首元结点的地址保存在头结点的指针域中,对链表的第一个数据元素的操作与其他数据元素相同,无需进行特殊处理。
- 便于空表和非空表的统一处理
- 当链表不设头结点时,假设
L
为单链表的头指针,它应该指向首元结点,则当链表为空表时,头指针为空(判定空表的条件为:L==NULL
)。
- 增加头结点后,无论链表是否为空,头指针都是指向头结点的非空指针。则当链表为空表时,头结点指针域为空(判定空表的条件为:
L->next==NULL
)。
1 2 3 4 5 6 7 8 9
| bool InitList(LinkList& L) { L = new LNode; if (L == NULL) { return false; } L->next = NULL; return true; }
|
栈
栈是限定仅在表尾进行插入或删除操作的线性表。特点:后进先出
顺序栈(栈的顺序存储)
CodeOcean-SqStack.h
CodeOcean-SqStack.cpp
1 2 3 4 5 6 7
| #define MAXSIZE 100 typedef struct { SElemType* base; SElemType* top; int stacksize; }SqStack;
|
1 2 3 4 5 6 7 8 9 10
| bool InitStack(SqStack& S);
bool Push(SqStack& S, SElemType e);
bool Pop(SqStack& S, SElemType& e);
SElemType GetTop(SqStack S);
bool StackEmpty(SqStack S);
|
1 2 3 4 5 6 7 8 9 10
| bool InitStack(SqStack& S) { S.base = (SElemType*)malloc(sizeof(SElemType) * MAXSIZE); if (!S.base) { return false; } S.top = S.base; S.stacksize = MAXSIZE; return true; }
|
1 2 3 4 5 6 7 8
| bool Push(SqStack& S, SElemType e) { if (S.top-S.base==S.stacksize) { return false; } *S.top++ = e; return true; }
|
1 2 3 4 5 6 7 8 9
| bool Pop(SqStack& S, SElemType& e){ if (S.top==S.base) { return false; } e = *--S.top; return true; }
|
1 2 3 4 5 6 7 8 9
| SElemType GetTop(SqStack S) { if (S.top!=S.base) { return *(S.top - 1); } SElemType m= create_struct(); return m; }
|
1 2 3 4 5 6 7
| bool StackEmpty(SqStack S) { if (S.top == S.base) { return true; } return false; }
|
链栈(栈的链式存储)
CodeOcean-LinkStack.h
CodeOcean-LinkStack.cpp
1 2 3 4 5 6 7 8
| typedef struct StackNode { ElemType data; struct StackNode* next; }StackNode,*LinkStack;
|
1 2 3 4 5 6 7 8
| void InitStack(LinkStack& S);
bool Push(LinkStack& S,ElemType& e);
bool Pop(LinkStack& S,ElemType& e);
bool GetTop(LinkStack S, ElemType& e);
|
1 2 3 4
| void InitStack(LinkStack& S) { S = NULL; }
|
1 2 3 4 5 6 7 8 9 10 11 12
| bool Push(LinkStack& S, ElemType& e) { StackNode* p = (StackNode*)malloc(sizeof(StackNode)); if (p==NULL) { return false; } p->data = e; p->next = S; S = p; return true; }
|
1 2 3 4 5 6 7 8 9 10 11 12
| bool Pop(LinkStack& S,ElemType& e) { if (S==NULL) { return false; } e = S->data; StackNode* p = S; S = S->next; free(p); return true; }
|
1 2 3 4 5 6 7 8 9
| bool GetTop(LinkStack S, ElemType& e) { if (S!=NULL) { e = S->data; return true; } return false; }
|
队列
队列是限定仅在表尾(即队尾)进行插入而表头(即队头)进行删除操作的线性表。特点:先进先出
循环队列(队列的顺序存储)
CodeOcean-SqQueue.h
CodeOcean-SqQueue.cpp
1 2 3 4 5 6 7 8
| #define MAXSIZE 100
typedef struct { QElemType* base; int front; int rear; }SqQueue;
|
1 2 3 4 5 6 7 8 9 10
| bool InitQueue(SqQueue& Q);
int QueueLength(SqQueue Q);
bool EnQueue(SqQueue& Q, QElemType e);
bool DeQueue(SqQueue& Q, QElemType& e);
bool GetHead(SqQueue Q,QElemType& e);
|
1 2 3 4 5 6 7 8 9 10
| bool InitQueue(SqQueue& Q) { Q.base = (QElemType*)malloc(sizeof(QElemType) * MAXSIZE); if (!Q.base) { return false; } Q.front = Q.rear = 0; return true; }
|
1 2 3 4
| int QueueLength(SqQueue Q) { return (Q.rear - Q.front + MAXSIZE) % MAXSIZE; }
|
1 2 3 4 5 6 7 8 9 10
| bool EnQueue(SqQueue& Q, QElemType e) { if ((Q.rear + 1) % MAXSIZE == Q.front) { return false; } Q.base[Q.rear] = e; Q.rear = (Q.rear + 1) % MAXSIZE; return true; }
|
1 2 3 4 5 6 7 8 9 10
| bool DeQueue(SqQueue& Q, QElemType& e) { if (Q.front==Q.rear) { return false; } e = Q.base[Q.front]; Q.front = (Q.front + 1) % MAXSIZE; return true; }
|
1 2 3 4 5 6 7 8 9
| bool GetHead(SqQueue Q, QElemType& e) { if (Q.front!=Q.rear) { e = Q.base[Q.front]; return true; } return false; }
|
链队(队列的链式存储)
CodeOcean-LinkQueue.h
CodeOcean-LinkQueue.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13
|
typedef struct QNode { QElemType data; struct QNode* next; }QNode,*QueuePtr; typedef struct { QueuePtr front; QueuePtr rear; }LinkQueue;
|
1 2 3 4 5 6 7 8
| bool InitQueue(LinkQueue& Q);
bool EnQueue(LinkQueue& Q, QElemType e);
bool DeQueue(LinkQueue& Q, QElemType& e);
bool GetHead(LinkQueue Q,QElemType& e);
|
1 2 3 4 5 6 7 8 9 10
| bool InitQueue(LinkQueue& Q) { Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode)); if (!Q.front || !Q.rear) { return false; } Q.front->next = NULL; return true; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| bool EnQueue(LinkQueue& Q, QElemType e) { QNode* p = (QueuePtr)malloc(sizeof(QNode)); if (!p) { return false; } p->data = e; p->next = NULL; Q.rear->next = p; Q.rear = p; return true; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| bool DeQueue(LinkQueue& Q, QElemType& e) { if (Q.front==Q.rear) { return false; } QNode* p = Q.front->next; e = p->data; Q.front->next = p->next; if (Q.rear==p) { Q.rear = Q.front; } free(p); }
|
1 2 3 4 5 6 7 8 9
| bool GetHead(LinkQueue Q, QElemType& e) { if (Q.front!=Q.rear) { e = Q.front->next->data; return true; } return false; }
|
串
CodeOcean-CString.h
CodeOcean-CString.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #define MAXLEN 255 typedef struct { char ch[MAXLEN + 1]; int length; }SString;
typedef struct { char* ch; int length; }HString;
#define CHUNKSIZE 80 typedef struct Chunk { char ch[CHUNKSIZE]; struct Chunk* next; }Chunk; typedef struct { Chunk* head, * tail; int length; }LString;
|
1 2 3 4 5 6 7 8
| int Index_BF(SString S, SString T, int pos);
void get_next(SString T, int next[]);
int Index_KMP(SString S, SString T, int pos, int next[]);
void get_nextval(SString T, int nextval[]);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| int Index_BF(SString S, SString T, int pos) { int i = pos; int j = 1; while (i <= S.length && j <= T.length) { if (S.ch[i] == T.ch[j]) { ++i; ++j; } else { i = i - j + 2; j = 1; } } if (j > T.length) { return i - T.length; } else { return 0; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| int Index_KMP(SString S, SString T, int pos, int next[]) { int i = pos; int j = 1; while (i <= S.length && j <= T.length) { if (j == 0 || S.ch[i] == T.ch[j]) { ++i; ++j; } else { j = next[j]; } } if (j > T.length) { return i - T.length; } else { return 0; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void get_next(SString T, int next[]) { int i = 1; next[1] = 0; int j = 0; while (i < T.length) { if (j == 0 || T.ch[i] == T.ch[j]) { ++i; ++j; next[i] = j; } else { j = next[j]; } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| void get_nextval(SString T, int nextval[]) { int i = 1; nextval[1] = 0; int j = 0; while (i < T.length) { if (j == 0 || T.ch[i] == T.ch[j]) { ++i; ++j; if (T.ch[i] != T.ch[j]) { nextval[i] = j; } else { nextval[i] = nextval[j]; } } else { j = nextval[j]; } } }
|
树和二叉树
CodeOcean-BiTree.h
CodeOcean-BiTree.cpp
图
CodeOcean-Graph.h
CodeOcean-Graph.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #define MaxInt 32767 #define MVNum 16 typedef char VerTexType; typedef int ArcType;
typedef struct { VerTexType vexs[MVNum]; ArcType arcs[MVNum][MVNum]; int vexnum, arcnum; }AMGraph;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| typedef int OtherInfo;
typedef struct ArcNode { int adjvex; struct ArcNode* nextarc; OtherInfo info; }ArcNode; typedef struct VNode { VerTexType data; ArcNode* firstArc; }AdjList[MVNum]; typedef struct { AdjList vertices; int vexnum, arcnum; }ALGraph;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int LocateVex(AMGraph G, VerTexType u);
bool CreateUDN(AMGraph& G);
bool CreateDG(AMGraph& G);
void GraphTraverse(AMGraph G);
bool GreatUDG(ALGraph& G);
int LocateVex(ALGraph G, VerTexType u);
void GraphTraverse(ALGraph G);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
extern bool visited[MVNum];
void DFS_AM(AMGraph G, int v);
void DFS_AL(ALGraph G, int v);
void DFS(AMGraph G); void DFS(ALGraph G);
void BFS_AM(AMGraph G, int v);
void BFS_AL(ALGraph G, int v);
void BFS(AMGraph G); void BFS(ALGraph G);
|
1 2 3 4 5 6 7
| struct { VerTexType adjvex; ArcType lowcost; }closedge[MVNum];
void MiniSpanTree_Prim(AMGraph G, VerTexType u);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| struct Edge { VerTexType Head; VerTexType Tail; ArcType lowcost; };
int Edge_Compare(Edge a, Edge b);
void Edge_Change(Edge& a, Edge& b);
extern int Vexset[MVNum];
void MiniSpanTree_Kruskal(AMGraph G);
|
1 2 3 4 5 6 7 8 9 10 11
|
extern bool S[MVNum];
extern int Path[MVNum];
extern ArcType D[MVNum];
void ShortestPath_DIJ(AMGraph G, int v0);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| bool CreateUDN(AMGraph& G) { printf("输入总顶点数:\n"); G.vexnum = intCin(); printf("输入总边数:\n"); G.arcnum = intCin(); printf("依次输入顶点信息\n"); for (int i = 0; i < G.vexnum; i++) { printf("输入...\n"); Clean(); G.vexs[i] = getchar(); } for (int i = 0; i < G.vexnum; i++) { for (int j = 0; j < G.vexnum; j++) { G.arcs[i][j] = MaxInt; } } for (int k = 0; k < G.arcnum; k++) { printf("输入一条边依附的顶点和权值\n"); printf("请输入边的权值\n"); int w = intCin(); printf("请输入其中一个顶点信息\n"); Clean(); char v1 = getchar(); printf("请输入另外一个顶点信息\n"); Clean(); char v2 = getchar(); int i = LocateVex(G, v1); int j = LocateVex(G, v2); G.arcs[i][j] = w; G.arcs[j][i] = G.arcs[i][j]; } return true; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| bool CreateDG(AMGraph& G) { printf("输入总顶点数:\n"); G.vexnum = intCin(); printf("输入总边数:\n"); G.arcnum = intCin(); printf("依次输入顶点信息\n"); for (int i = 0; i < G.vexnum; i++) { printf("输入...\n"); Clean(); G.vexs[i] = getchar(); } for (int i = 0; i < G.vexnum; i++) { for (int j = 0; j < G.vexnum; j++) { G.arcs[i][j] = MaxInt; if (i == j) { G.arcs[i][j] = 0; } } } for (int k = 0; k < G.arcnum; k++) { printf("输入一条边依附的顶点和权值\n"); printf("请输入边的权值\n"); int w = intCin(); printf("请输入始点(弧尾)信息\n"); Clean(); char v1 = getchar(); printf("请输入终点(弧头)信息\n"); Clean(); char v2 = getchar(); int i = LocateVex(G, v1); int j = LocateVex(G, v2); G.arcs[i][j] = w; } return true; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| bool GreatUDG(ALGraph& G) { printf("输入总顶点数:\n"); G.vexnum = intCin(); printf("输入总边数:\n"); G.arcnum = intCin(); printf("依次输入顶点信息\n"); for (int i = 0; i < G.vexnum; i++) { printf("输入...\n"); Clean(); G.vertices[i].data = getchar(); G.vertices[i].firstArc = NULL; } for (int k = 0; k < G.arcnum; k++) { printf("输入一条边依附的顶点\n"); printf("请输入其中一个顶点信息\n"); Clean(); char v1 = getchar(); printf("请输入另外一个顶点信息\n"); Clean(); char v2 = getchar(); int i = LocateVex(G, v1); int j = LocateVex(G, v2); ArcNode* p1 = (ArcNode*)malloc(sizeof(ArcNode)); if (p1==NULL) { return false; } p1->adjvex = j; p1->nextarc = G.vertices[i].firstArc; G.vertices[i].firstArc = p1; ArcNode* p2 = (ArcNode*)malloc(sizeof(ArcNode)); if (p2==NULL) { return false; } p2->adjvex = i; p2->nextarc = G.vertices[j].firstArc; G.vertices[j].firstArc = p2; } return true; }
|
1 2 3 4 5 6 7 8 9 10 11
| int LocateVex(AMGraph G, VerTexType u) { for (int i = 0; i < G.vexnum; i++) { if (G.vexs[i] == u) { return i; } } return -1; }
|
1 2 3 4 5 6 7 8 9 10
| int LocateVex(ALGraph G, VerTexType u) { for (int i = 0; i < G.vexnum; i++) { if (G.vertices[i].data==u) { return i; } } return -1; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void GraphTraverse(AMGraph G) { printf("图的顶点信息如下:\n"); for (int i = 0; i < G.vexnum; i++) { printf("%c\t", G.vexs[i]); } printf("\n"); printf("图的邻接矩阵如下:\n"); for (int i = 0; i < G.vexnum; i++) { for (int j = 0; j < G.vexnum; j++) { printf("%d\t", G.arcs[i][j]); } printf("\n"); } }
|
1 2 3 4 5 6 7 8
| void GraphTraverse(ALGraph G) { printf("图的顶点信息如下:\n"); for (int i = 0; i < G.vexnum; i++) { printf("%c\t", G.vertices[i].data); } printf("\n"); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void DFS_AM(AMGraph G, int v) {
printf("%c\t",G.vexs[v]); visited[v] = true; for (int w = 0; w < G.vexnum; w++) { if (G.arcs[v][w] != MaxInt && !visited[w]) { DFS_AM(G, w); } } } void DFS(AMGraph G) { for (int i = 0; i < MVNum; i++) { visited[i] = false; } DFS_AM(G, 0); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| void DFS_AL(ALGraph G, int v) { printf("%c\t", G.vertices[v].data); visited[v] = true; ArcNode* p = G.vertices[v].firstArc; while (p!=NULL) { int w = p->adjvex; if (!visited[w]) { DFS_AL(G, w); } p = p->nextarc; } } void DFS(ALGraph G) { for (int i = 0; i < MVNum; i++) { visited[i] = false; } DFS_AL(G, 0); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| void BFS_AM(AMGraph G, int v) { printf("%c\t", G.vexs[v]); visited[v] = true; SqQueue Q; InitQueue(Q); EnQueue(Q, G.vexs[v]); while (!QueueEmpty(Q)) { VerTexType u; DeQueue(Q, u); int index = LocateVex(G, u); for (int w = 0; w < G.vexnum; w++) { if ((G.arcs[index][w] != MaxInt) && (!visited[w])) { printf("%c\t", G.vexs[w]); visited[w] = true; EnQueue(Q, w); } } } } void BFS(AMGraph G) { for (int i = 0; i < MVNum; i++) { visited[i] = false; } BFS_AM(G, 0); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| void BFS_AL(ALGraph G, int v) { printf("%c\t", G.vertices[v].data); visited[v] = true; SqQueue Q; InitQueue(Q); EnQueue(Q, G.vertices[v].data); while (!QueueEmpty(Q)) { VerTexType u; DeQueue(Q, u); int index = LocateVex(G, u); ArcNode* p = G.vertices[index].firstArc; while (p != NULL) { int w = p->adjvex; if (!visited[w]) { printf("%c\t", G.vertices[w].data); visited[w] = true; EnQueue(Q, G.vertices[w].data); } p = p->nextarc; } } } void BFS(ALGraph G) { for (int i = 0; i < MVNum; i++) { visited[i] = false; } BFS_AL(G, 0); }
|
查找
CodeOcean-Search.h
CodeOcean-Search.cpp
排序
CodeOcean-sort.h
CodeOcean-sort.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| void TraverseArray(ElemType A[], int n);
void InsertSort(ElemType A[], int n);
void BinaryInsertSort(ElemType A[], int n);
void ShellInsert(ElemType A[],int n, int dk);
void ShellSort(ElemType A[], int n);
void BubbleSort(ElemType A[], int n);
void QuickSort(ElemType A[], int n);
void SelectSort(ElemType A[], int n);
void HeapSort(ElemType A[], int n);
void MergeSort(ElemType R[], int n); void MergeSort(ElemType A[], int low, int high);
#define MAXNUM_KEY 8 #define RADIX 10 #define MAXSIZE 100 typedef int KeyType; typedef struct { KeyType keys[MAXNUM_KEY]; char otherItems[16]; int next; }SLCell; typedef struct { SLCell r[MAXSIZE]; int keynum; int length; }SLList; typedef int ArrType[RADIX];
void SLListInit(SLList& L, KeyType keys[], int len, int keynum);
void RadixSort(SLList& L);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void InsertSort(ElemType A[], int n) { int i, j; for (i = 2; i <= n; i++) { if (A[i] < A[i - 1]) { A[0] = A[i]; for (j = i - 1; A[0] < A[j]; j--) { A[j + 1] = A[j]; } A[j + 1] = A[0]; } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| void BinaryInsertSort(ElemType A[], int n) { int i, j, low, high, mid; for (i = 2; i <= n; i++) { A[0] = A[i]; low = 1; high = i - 1; while (low <= high) { mid = (low + high) / 2; if (A[0] < A[mid]) { high = mid - 1; } else { low = mid + 1; } } for (j = i - 1; j >= high + 1; j--) { A[j + 1] = A[j]; } A[high + 1] = A[0]; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void ShellInsert(ElemType A[], int n,int dk) { int i, j; for (i = 1+dk; i <=n; i++) { if (A[i]<A[i-dk]) { A[0] = A[i]; for (j = i-dk; j >0 && A[0]<A[j] ; j-=dk) { A[j + dk] = A[j]; } A[j + dk] = A[0]; } } } void ShellSort(ElemType A[], int n) { for (int dk = n/2; dk >=1 ; dk=dk/2) { ShellInsert(A, n, dk); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| void BubbleSort(ElemType A[], int n) { for (int i = 1; i <n; i++) { bool flag = false; for (int j = n; j >i; j--) { if (A[j-1]>A[j]) { A[0] = A[j]; A[j] = A[j - 1]; A[j - 1] = A[0]; flag = true; } } if (!flag) { return; } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| int Partition(ElemType A[],int low,int high) { ElemType pivot = A[low]; while (low<high) { while (low<high && A[high]>=pivot) { high--; } A[low] = A[high]; while (low<high && A[low]<=pivot) { low++; } A[high] = A[low]; } A[low] = pivot; return low; }
void QSort(ElemType A[], int low, int high) { if (low<high) { int pivotpos = Partition(A, low, high); QSort(A, low, pivotpos - 1); QSort(A, pivotpos + 1, high); } } void QuickSort(ElemType A[],int n) { QSort(A, 1, n); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void SelectSort(ElemType A[], int n) { for (int i = 1; i < n; i++) { int min = i; for (int j = i+1; j <= n; j++) { if (A[j]<A[min]) { min = j; } } if (min!=i) { A[0] = A[i]; A[i] = A[min]; A[min] = A[0]; } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| void HeapAdjust(ElemType A[], int s,int m) { A[0] = A[s]; for (int i = 2*s; i <=m; i*=2) { if (i<m && A[i]<A[i+1]) { i++; } if (A[0]>=A[i]) { break; } A[s] = A[i]; s = i; } A[s] = A[0]; } void CreatMaxHeap(ElemType A[],int n) { for (int i = n/2; i > 0; i--) { HeapAdjust(A, i, n); } } void HeapSort(ElemType A[], int n) { CreatMaxHeap(A, n); for (int i = n; i>1; i--) { A[0] = A[i]; A[i] = A[1]; A[1] = A[0]; HeapAdjust(A, 1, i - 1); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| void Merge(ElemType R[], ElemType T[], int low, int mid, int high) { int i = low, j = mid + 1, k = low; while (i <= mid && j <= high) { if (R[i] <= R[j]) { T[k++] = R[i++]; } else { T[k++] = R[j++]; } } while (i <= mid) { T[k++] = R[i++]; } while (j <= high) { T[k++] = R[j++]; } } void MSort(ElemType R[], ElemType T[], int low, int high) { if (low == high) { T[low] = R[low]; } else { ElemType* S = (ElemType*)malloc((high + 1) * sizeof(ElemType)); int mid = (low + high) / 2; MSort(R, S, low, mid); MSort(R, S, mid + 1, high); Merge(S, T, low, mid, high); free(S); } } void MergeSort(ElemType R[],int n) { MSort(R, R, 1, n); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| ElemType B[9] = {0};
void Merge(ElemType A[],int low,int mid,int high) { int i=low, j=mid+1, k=low; for (int x = low; x <= high; x++) { B[x] = A[x]; } while (i <= mid && j <= high) { if (B[i] <= B[j]) { A[k++] = B[i++]; } else { A[k++] = B[j++]; } } while (i<=mid) { A[k++] = B[i++]; } while (j<=high) { A[k++] = B[j++]; } } void MergeSort(ElemType A[], int low, int high) { if (low < high) { int mid = (low + high) / 2; MergeSort(A, low, mid); MergeSort(A, mid + 1, high); Merge(A, low, mid, high); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| void SLListInit(SLList& L, KeyType keys[], int len, int keynum) { L.keynum = keynum; L.length = len; for (int i = 1; i <= len; i++) { L.r[i].keys[2] = keys[i] / 100; L.r[i].keys[1] = keys[i] % 100 / 10; L.r[i].keys[0] = keys[i] % 10; } } void Distribute(SLList& L,int i, ArrType& f, ArrType& e) { for (int j = 0; j < RADIX; j++) { f[j] = 0; } for (int p = L.r[0].next; p ; p=L.r[p].next) { int key = L.r[p].keys[i]; if (!f[key]) { f[key] = p; } else { L.r[e[key]].next = p; } e[key] = p; } } void Collect(SLList& L, int i, ArrType f, ArrType e) { int j; for (j = 0; !f[j]; j++) {} L.r[0].next = f[j]; int t = e[j]; while(j < RADIX) { for (j = j + 1; j < RADIX - 1 && !f[j]; j++) {} if (j != RADIX && f[j]) { L.r[t].next = f[j]; t = e[j]; } } L.r[t].next = 0; } void RadixSort(SLList& L) { ArrType f, e; for (int i = 0; i < L.length; i++) { L.r[i].next = i + 1; } L.r[L.length].next = 0; for (int i = 0; i < L.keynum; i++) { Distribute(L, i, f, e); Collect(L, i, f, e); } }
|