一、 顺序表
1. 元素之和
/*
【问题描述】1、已知顺序表中的数据元素为整型,试写一算法计算所有元素之和。
【输入形式】
元素个数
按照任意顺序输入多个正整数,每个数之间用一个空格隔开
【输出形式】所有元素之和
【样例输入】
6
1 2 4 5 3 7
【样例输出】22
【样例说明】共有5组测试样例
【评分标准】要求必须使用顺序存储
*/
#include <stdio.h>
#include <stdlib.h>
#define list_init_size 100
#define listincrement 10
typedef struct
{
int *elem;
int length;
int listsize;
}SQLIST;//定义结构体类型的数据类型
int initlist_SQ(SQLIST &L)
{
L.elem=(int *) malloc (list_init_size*sizeof(int));
if (!L.elem)
exit (-1);
L.length=0;
L.listsize=list_init_size;
return 1;
}//构造一个空的线性表
int input(SQLIST &L)
{
int i=0,n=0;
int sum=0;
//printf("请先输入数据个数,再输入数据元素\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&L.elem[i]);
sum+=L.elem[i];
}
return sum;
}//输入函数
int main()
{
int SUM=0;
SQLIST LL;
initlist_SQ(LL);
SUM=input(LL);
//printf("数据元素的和为:\n");
printf("%d\n",SUM);
return 1;
//system("pause");
}
2. 逆序
/*
【问题描述】试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1,...,an)逆置为(an,...,a1)。
【输入形式】连续输入多个正整数,每数之间以一个空格隔开,最后一个数为-1作为结束标志。
如 1 2 3 4 5 -1
【输出形式】把输入的正整数逆序输出,每数之间以一个空格隔开。 如 5 4 3 2 1
【样例输入】1 2 3 4 5 -1
【样例输出】5 4 3 2 1
【样例说明】
【评分标准】
*/
#include <stdio.h>
#include <stdlib.h>
#define list_size 100
#define listincrement 10
typedef struct
{
int *elem;
int length;
int listsize;
}SQLIST;//定义结构体类型的数据类型
int initlist_SQ(SQLIST &L)
{
L.elem=(int *) malloc (list_size*sizeof(int));
if (!L.elem)
exit (-1);
L.length=0;
L.listsize=list_size;
return 1;
}//构造一个空的线性表
int input(SQLIST &L)
{
int i=0,n=0,k;
//printf("请输入数据元素,以-1结束\n");
for(i=0;;i++)
{
scanf("%d",&k);
if(k==-1)
break;
else
{
L.elem[i]=k;
L.length++;
}
}
return 1;
}//输入函数
int nixuhanshu(SQLIST &L)
{
int i=0,n=0,e=0;
n=L.length/2;
for(i=0;i<n;i++)//逆序
{
e=L.elem[i];
L.elem[i]=L.elem[L.length-1-i];
L.elem[L.length-1-i]=e;
}
//printf("数据元素的逆序为:\n");
for(i=0;i<L.length;i++)//输出
{
printf("%d ",L.elem[i]);
}
//printf("\n");
return 1;
}//实现逆序并输出的函数
int main ()
{
SQLIST LL;
initlist_SQ(LL);
input(LL);
nixuhanshu(LL);
return 1;
//system("pause");
}
3. 交集
#include <stdio.h>
#include <stdlib.h>
#define list_init_size 100
#define listincrement 10
typedef struct
{
int *elem;
int length;
int listsize;
}SQLIST;//定义结构体类型的数据类型
int initlist_SQ(SQLIST &L)
{
L.elem=(int *) malloc (list_init_size*sizeof(int));
if (!L.elem)
exit (-1);
L.length=0;
L.listsize=list_init_size;
return 1;
}//构造一个空的线性表
int input(SQLIST &L)
{
int i=0,n=0;
printf("请以非递减顺序输入顺序表数据元素并以-1结束:\n");
for(i=0;;i++)
{
//L.elem[i]=0;
scanf("%d",&n);
if(n==-1)
break;
else if (L.elem[i]<=n)
{
L.elem[i]=n;
L.length++;
}
else
break;
// return -1;
}
return 1;
}//输入函数
/*
int input(SQLIST &L)
{
int i=0,n=0,m=0;
printf("请以非递减顺序输入顺序表数据元素并以-1结束:\n");
for(i=0;;i++)
{
//L.elem[i]=0;
scanf("%d",&n);
if(n==-1)
break;
scanf("%d",&m);
if(m==-1)
{
L.elem[i]=n;
break;
}
else if (m<n)
{
printf("该序列不是非递减序列请重新输入:\n");
continue;
}
else
{
L.elem[i]=n;
L.elem[i+1]=m;
L.length+=2;
}
}
return 1;
}*/
int qiujiao(SQLIST L,SQLIST LL,SQLIST &LLL)
{
int i=0,j=0;
printf("两顺序表求交后的数据元素为:\n");
for(i=0;i<L.length;i++)
{
for(j=0;j<LL.length;j++)
{
if(L.elem[i]==LL.elem[j])
{
LLL.elem[i]=L.elem[i];
LLL.length++;
printf("%d ",LLL.elem[i]);//输出两顺序表求交后的数据元素
}
else if(L.elem[i]<LL.elem[j])
break;
else
continue;
}
}
return 1;
}//求交集的函数
int main()
{
SQLIST LA,LB,LC;
initlist_SQ(LA);
initlist_SQ(LB);
initlist_SQ(LC);
input(LA);
input(LB);
qiujiao(LA,LB,LC);
return 1;
//system("pause");
}
4. 哈希表
// Hash表实现代码:
#include <stdio.h>
#include <malloc.h>
#define NULLKEY 0 // 0为无记录标志
#define N 10 // 数据元素个数
typedef int KeyType;// 设关键字域为整型
typedef struct
{
KeyType key;
int ord;
}ElemType; // 数据元素类型
int hashsize[] = { 11, 19, 29, 37 }; // 哈希表容量递增表,一个合适的素数序列// 开放定址哈希表的存储结构
int m = 0; // 哈希表表长,全局变量
typedef struct
{
ElemType *elem; // 数据元素存储基址,动态分配数组
int count; // 当前数据元素个数
int sizeindex; // hashsize[sizeindex]为当前容量
}HashTable;
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1
int InitHashTable(HashTable *H)// 构造一个空的哈希表
{
int i;
(*H).count = 0; // 当前元素个数为0
(*H).sizeindex = 0; // 初始存储容量为hashsize[0]
m = hashsize[0];
(*H).elem = (ElemType*)malloc(m*sizeof(ElemType));
if (!(*H).elem)
return 0; // 存储分配失败
for (i = 0; i<m; i++)
(*H).elem[i].key = NULLKEY; // 未填记录的标志
return 1;
}
void DestroyHashTable(HashTable *H)// 销毁哈希表H
{
free((*H).elem);
(*H).elem = NULL;
(*H).count = 0;
(*H).sizeindex = 0;
}
unsigned Hash(KeyType K)// 一个简单的哈希函数(m为表长,全局变量)
{
return K%m;
}
void collision(int *p, int d) // 线性探测再散列// 开放定址法处理冲突
{
*p = (*p + d) % m;
}
int SearchHash(HashTable H, KeyType K, int *p, int *c)// 在开放定址哈希表H中查找关键码为K的元素,若查找成功,以p指示待查数据
{// 元素在表中位置,并返回SUCCESS;否则,以p指示插入位置,并返回UNSUCCESS // c用以计冲突次数,其初值置零,供建表插入时参考。
*p = Hash(K); // 求得哈希地址
while (H.elem[*p].key != NULLKEY&&!(K == H.elem[*p].key))
{
// 该位置中填有记录.并且关键字不相等
(*c)++;
if (*c<m)
collision(p, *c); // 求得下一探查地址p
else
break;
}
if (K == H.elem[*p].key)
return SUCCESS; // 查找成功,p返回待查数据元素位置
else
return UNSUCCESS; // 查找不成功(H.elem[p].key==NULLKEY),p返回的是插入位置
}
int InsertHash(HashTable *, ElemType); // 对函数的声明
void RecreateHashTable(HashTable *H) // 重建哈希表
{
int i, count = (*H).count;
ElemType *p, *elem = (ElemType*)malloc(count*sizeof(ElemType));
p = elem;
printf("重建哈希表\n");
for (i = 0; i<m; i++) // 保存原有的数据到elem中
if (((*H).elem + i)->key != NULLKEY) // 该单元有数据
*p++ = *((*H).elem + i);
(*H).count = 0;
(*H).sizeindex++; // 增大存储容量
m = hashsize[(*H).sizeindex];
p = (ElemType*)realloc((*H).elem, m*sizeof(ElemType));
if (!p)
return; // 存储分配失败
(*H).elem = p;
for (i = 0; i<m; i++)
(*H).elem[i].key = NULLKEY; // 未填记录的标志(初始化)
for (p = elem; p<elem + count; p++) // 将原有的数据按照新的表长插入到重建的哈希表中
InsertHash(H, *p);
}
int InsertHash(HashTable *H, ElemType e)// 查找不成功时插入数据元素e到开放定址哈希表H中,并返回1;// 若冲突次数过大,则重建哈希表。
{
int c, p;
c = 0;
if (SearchHash(*H, e.key, &p, &c)) // 表中已有与e有相同关键字的元素
return DUPLICATE;
else if (c < hashsize[(*H).sizeindex] / 2) // 冲突次数c未达到上限,(c的阀值可调)
{
// 插入e
(*H).elem[p] = e;
++(*H).count;
return 1;
}
else
RecreateHashTable(H); // 重建哈希表
return 0;
}
void TraverseHash(HashTable H, void(*Vi)(int, ElemType))// 按哈希地址的顺序遍历哈希表
{
int i;
printf("哈希地址0~%d\n", m - 1);
for (i = 0; i<m; i++)
if (H.elem[i].key != NULLKEY) // 有数据
Vi(i, H.elem[i]);
}
int Find(HashTable H, KeyType K, int *p)// 在开放定址哈希表H中查找关键码为K的元素,若查找成功,以p指示待查数据// 元素在表中位置,并返回SUCCESS;否则,返回UNSUCCESS
{
int c = 0;
*p = Hash(K); // 求得哈希地址
while (H.elem[*p].key != NULLKEY&&!(K == H.elem[*p].key))
{ // 该位置中填有记录.并且关键字不相等
c++;
if (c<m)
collision(p, c); // 求得下一探查地址p
else
return UNSUCCESS; // 查找不成功(H.elem[p].key==NULLKEY)
}
if (K == H.elem[*p].key)
return SUCCESS; // 查找成功,p返回待查数据元素位置
else
return UNSUCCESS; // 查找不成功(H.elem[p].key==NULLKEY)
}
void print(int p, ElemType r)
{
printf("address=%d (%d,%d)\n", p, r.key, r.ord);
}
int main()
{
ElemType r[N] = {
{ 17, 1 }, { 60, 2 }, { 29, 3 }, { 38, 4 }, { 1, 5 },
{ 2, 6 }, { 3, 7 }, { 4, 8 }, { 60, 9 }, { 13, 10 }
};
HashTable h;
int i, j, p;
KeyType k;
InitHashTable(&h);
for (i = 0; i<N - 1; i++)
{ // 插入前N-1个记录
j = InsertHash(&h, r[i]);
if (j == DUPLICATE)
printf("表中已有关键字为%d的记录,无法再插入记录(%d,%d)\n",
r[i].key, r[i].key, r[i].ord);
}
printf("按哈希地址的顺序遍历哈希表:\n");
TraverseHash(h, print);
printf("请输入待查找记录的关键字: ");
scanf("%d", &k);
j = Find(h, k, &p);
if (j == SUCCESS)
print(p, h.elem[p]);
else
printf("没找到\n");
j = InsertHash(&h, r[i]); // 插入第N个记录
if (j == 0) // 重建哈希表
j = InsertHash(&h, r[i]); // 重建哈希表后重新插入第N个记录
printf("按哈希地址的顺序遍历重建后的哈希表:\n");
TraverseHash(h, print);
printf("请输入待查找记录的关键字: ");
scanf("%d", &k);
j = Find(h, k, &p);
if (j == SUCCESS)
print(p, h.elem[p]);
else
printf("没找到\n");
DestroyHashTable(&h);
return 0;
}
5. 顺序查找
#include <stdio.h>
#include <malloc.h>
#define N 5 // 数据元素个数
typedef int KeyType; // 设关键字域为整型
typedef struct // 数据元素类型(以教科书P215图9.1高考成绩为例)
{
long number; // 准考证号
char name[9]; // 姓名(4个汉字加1个串结束标志)
int politics; // 政治
int Chinese; // 语文
int English; // 英语
int math; // 数学
int physics; // 物理
int chemistry; // 化学
int biology; // 生物
KeyType key; // 关键字类型应为KeyType,域名应为key
} ElemType;
typedef struct
{
ElemType *elem;// 数据元素存储空间基址,建表时按实际长度分配,0号单元留空
int length; // 表长度
}SSTable;
ElemType r[N] = {
{ 179324, "何芳芳", 85, 89, 98, 100, 93, 80, 47 },
{ 179325, "陈红", 85, 86, 88, 100, 92, 90, 45 },
{ 179326, "陆华", 78, 75, 90, 80, 95, 88, 37 },
{ 179327, "张平", 82, 80, 78, 98, 84, 96, 40 },
{ 179328, "赵小怡", 76, 85, 94, 57, 77, 69, 44 }
}; // 全局变量
#define total key // 定义总分(total)为关键字
int Creat_Seq(SSTable *ST, int n)// 构造一个含n个数据元素的静态顺序查找表ST(数据来自全局数组r)。
{
int i;
(*ST).elem = (ElemType *)calloc(n + 1, sizeof(ElemType));// 动态生成n+1个数据元素空间(0号单元不用)
if (!(*ST).elem)
return 0;
for (i = 1; i <= n; i++)
*((*ST).elem + i) = r[i - 1]; // 将全局数组r的值依次赋给ST
(*ST).length = n;
return 1;
}
void Ascend(SSTable *ST)// 重建静态查找表为按关键字非降序排序。
{
int i, j, k;
for (i = 1; i<(*ST).length; i++)
{
k = i;
(*ST).elem[0] = (*ST).elem[i]; // 待比较值存[0]单元
for (j = i + 1; j <= (*ST).length; j++)
if ((*ST).elem[j].key < (*ST).elem[0].key)
{
k = j;
(*ST).elem[0] = (*ST).elem[j];
}
if (k != i) // 有更小的值则交换
{
(*ST).elem[k] = (*ST).elem[i];
(*ST).elem[i] = (*ST).elem[0];
}
}
}
int Creat_Ord(SSTable *ST, int n)// 构造一个含n个数据元素的静态按关键字非降序查找表ST。// 数据来自全局数组r。
{
int f;
f = Creat_Seq(ST, n);
if (f)
Ascend(ST);
return f;
}
int Destroy(SSTable *ST)// 销毁表ST。
{
free((*ST).elem);
(*ST).elem = NULL;
(*ST).length = 0;
return 1;
}
int Traverse(SSTable ST, void(*Visit)(ElemType))// 按顺序对ST的每个元素调用函数Visit()一次且仅一次。
{
ElemType *p;
int i;
p = ++ST.elem; // p指向第一个元素,第0个元素没有用
for (i = 1; i <= ST.length; i++)
Visit(*p++);
return 1;
}
int Search_Seq(SSTable ST, KeyType key)// 在顺序表ST中顺序查找其关键字等于key的数据元素。若找到,则函数// 值为该元素在表中的位置,否则为0。
{
int i;
ST.elem[0].key = key; // 哨兵
for (i = ST.length; !(ST.elem[i].key == key); --i); // 从后往前找
return i; // 找不到时,i为0
}
void print(ElemType c) // Traverse()调用的函数
{
printf("%-8ld%-8s%4d%5d%5d%5d%5d%5d%5d%5d\n",
c.number, c.name, c.politics, c.Chinese, c.English,
c.math, c.physics, c.chemistry, c.biology, c.total);
}
int main()
{
SSTable st;
int i, s;
for (i = 0; i<N; i++) // 计算总分
r[i].total = r[i].politics + r[i].Chinese +
r[i].English + r[i].math
+ r[i].physics + r[i].chemistry + r[i].biology;
Creat_Seq(&st, N); // 由全局数组产生静态查找表st
printf("准考证号姓名政治语文外语数学物理化学生物总分\n");
Traverse(st, print); // 按顺序输出静态查找表st
printf("请输入待查找人的总分: ");
scanf_s("%d", &s);
i = Search_Seq(st, s); // 顺序查找
if (i)
print(*(st.elem + i));
else
printf("没找到\n");
Destroy(&st);
return 0;
}
6. 折半查找
// 折半查找实现代码
#include <stdio.h>
#include <malloc.h>
#define N 11 // 数据元素个数
typedef int KeyType; // 设关键字域为整型
typedef struct // 数据元素类型
{
KeyType key; // 关键字域
int others; // 其它部分
}ElemType;
typedef struct// Search_Seq.h 静态查找表的顺序存储结构
{
ElemType *elem; // 数据元素存储空间基址,建表时按实际长度分配,0号单元留空
int length; // 表长度
}SSTable;
ElemType r[N] = {
{ 05, 1 }, { 13, 2 }, { 19, 3 }, { 21, 4 },
{ 37, 5 }, { 56, 6 }, { 64, 7 }, { 75, 8 },
{ 80, 9 }, { 88, 10 }, { 92, 11 }
}; // 数据元素,全局变量
int Creat_Seq(SSTable *ST, int n)// 静态查找表(顺序表和有序表)的基本操作(7个) // 构造一个含n个数据元素的静态顺序查找表ST(数据来自全局数组r)
{
int i;
(*ST).elem = (ElemType *)calloc(n + 1, sizeof(ElemType)); // 动态生成n + 1个数据元素空间(0号单元不用)
if (!(*ST).elem)
return 0;
for (i = 1; i <= n; i++)
*((*ST).elem + i) = r[i - 1]; // 将全局数组r的值依次赋给ST
(*ST).length = n;
return 1;
}
void Ascend(SSTable *ST)// 重建静态查找表为按关键字非降序排序
{
int i, j, k;
for (i = 1; i < (*ST).length; i++)
{
k = i;
(*ST).elem[0] = (*ST).elem[i]; // 待比较值存[0]单元
for (j = i + 1; j <= (*ST).length; j++) //从中找到第i小的值
if ((*ST).elem[j].key < (*ST).elem[0].key)
{
k = j;
(*ST).elem[0] = (*ST).elem[j];
}
if (k != i) // 有更小的值则交换
{
(*ST).elem[k] = (*ST).elem[i];
(*ST).elem[i] = (*ST).elem[0];
}
}
}
int Creat_Ord(SSTable *ST, int n)// 构造一个含n个数据元素的静态按关键字非降序查找表ST,// 数据来自全局数组r
{
int f;
f = Creat_Seq(ST, n); //构建一个静态表
if (f) //静态表存在,则对其进行重建
Ascend(ST);
return f;
}
int Destroy(SSTable *ST)// 销毁表ST
{
free((*ST).elem);
(*ST).elem = NULL;
(*ST).length = 0;
return 1;
}
int Search_Bin(SSTable ST, KeyType key)// 在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数// 值为该元素在表中的位置,否则为0。
{
int low, high, mid;
low = 1; // 置区间初值
high = ST.length;
while (low <= high)
{
mid = (low + high) / 2;
if (key == ST.elem[mid].key) // 找到待查元素
return mid;
else if (key < ST.elem[mid].key)
high = mid - 1; // 继续在前半区间进行查找
else
low = mid + 1; // 继续在后半区间进行查找
}
return 0; // 顺序表中不存在待查元素
}
int Traverse(SSTable ST, void(*Visit)(ElemType))// 按顺序对ST的每个元素调用函数Visit()一次且仅一次。
{
ElemType *p;
int i;
p = ++ST.elem; // p指向第一个元素,第0个元素没有用
for (i = 1; i <= ST.length; i++)
Visit(*p++);
return 1;
}
void print(ElemType c) // Traverse()调用的函数
{
printf("(%d %d) ", c.key, c.others);
}
int main()
{
SSTable st;
int i;
KeyType s;
Creat_Ord(&st, N); // 由全局数组产生非降序静态查找表st
Traverse(st, print); // 顺序输出非降序静态查找表st
printf("\n请输入待查找值的关键字: ");
scanf("%d", &s);
i = Search_Bin(st, s); // 折半查找有序表
if (i)
print(st.elem[i]);
else
printf("没找到.\n");
Destroy(&st);
return 0;
}
7. 快速排序
// 快速排序实现代码:
#include"stdio.h"
// 记录类型
typedef int KeyType; // 定义关键字类型为整型
typedef int InfoType; // 定义其它数据项的类型
typedef struct
{
KeyType key; // 关键字项
InfoType otherinfo; // 其它数据项
}RedType;
#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度
// 顺序表类型
typedef struct
{
RedType r[MAXSIZE + 1]; // r[0]闲置或用作哨兵单元
int length; // 顺序表长度
}SqList;
// 打印顺序表
void print(SqList L)
{
int i;
for (i = 1; i <= L.length; i++)
printf("(%d, %d) ", L.r[i].key, L.r[i].otherinfo);
printf("\n\n");
}
// 交换顺序表L中子表L.r[low..high]的记录,使枢轴记录到位,
// 并返回其所在位置,此时在它之前(后)的记录均不大(小)于它。
int Partition(SqList *L, int low, int high)
{
RedType t;
KeyType pivotkey;
pivotkey = (*L).r[low].key; // 用子表的第一个记录作枢轴记录
while (low<high)
{
// 从表的两端交替地向中间扫描
while (low<high && (*L).r[high].key >= pivotkey)
--high;
t = (*L).r[low]; // 将比枢轴记录小的记录交换到低端
(*L).r[low] = (*L).r[high];
(*L).r[high] = t;
while (low<high && (*L).r[low].key <= pivotkey)
++low;
t = (*L).r[low]; // 将比枢轴记录大的记录交换到高端
(*L).r[low] = (*L).r[high];
(*L).r[high] = t;
}
return low; // 返回枢轴所在位置
}
#define N 8
int main()
{
RedType d[N] = {
{ 49, 1 }, { 38, 2 }, { 65, 3 }, { 97, 4 },
{ 76, 5 }, { 13, 6 }, { 27, 7 }, { 49, 8 }
};
SqList l;
int i;
for (i = 0; i<N; i++)
l.r[i + 1] = d[i];
l.length = N;
printf("快速排序a前:\n");
print(l);
QuickSort(&l);
printf("快速排序a后:\n");
print(l);
return 0;
}
8. 选择排序
// 选择排序实现代码:
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include <limits.h>
// 记录类型
typedef struct
{
int key; // 关键字项
int otherinfo; // 其它数据项
}RedType;
#define MAXSIZE 30 // 一个用作示例的小顺序表的最大长度
// 顺序表类型
typedef struct
{
RedType r[MAXSIZE + 1]; // r[0]闲置或用作哨兵单元
int length; // 顺序表长度
}SqList;
// 打印顺序表
void print(SqList L)
{
int i;
for (i = 1; i <= L.length; i++)
printf("(%d, %d) ", L.r[i].key, L.r[i].otherinfo);
printf("\n\n");
}
// 返回在L.r[i..L.length]中key最小的记录的序号
int SelectMinKey(SqList L, int i)
{
int min;
int j, k;
k = i; // 设第i个为最小
min = L.r[i].key;
for (j = i + 1; j <= L.length; j++)
if (L.r[j].key<min) // 找到更小的
{
k = j;
min = L.r[j].key;
}
return k;
}
// 对顺序表L作简单选择排序。
void SelectSort(SqList *L)
{
int i, j;
RedType t;
for (i = 1; i<(*L).length; ++i)
{
// 选择第i小的记录,并交换到位
j = SelectMinKey(*L, i); // 在L.r[i..L.length]中选择key最小的记录
if (i != j)
{
// 与第i个记录交换
t = (*L).r[i];
(*L).r[i] = (*L).r[j];
(*L).r[j] = t;
}
}
}
#define N 8
int main()
{
RedType d[N] = {
{ 49, 1 }, { 38, 2 }, { 65, 3 }, { 97, 4 },
{ 76, 5 }, { 13, 6 }, { 27, 7 }, { 49, 8 }
};
SqList l;
int i;
for (i = 0; i<N; i++)
l.r[i + 1] = d[i];
l.length = N;
printf("排序前:\n");
print(l);
SelectSort(&l);
printf("简单选择排序后:\n");
print(l);
return 0;
}
9. 其他排序
#include <stdio.h>
#include <malloc.h>
typedef int KeyType; // 定义关键字类型为整型
typedef int InfoType; // 定义其它数据项的类型
// 记录类型
typedef struct
{
KeyType key; // 关键字项
InfoType otherinfo; // 其它数据项
}RedType;
#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度
// 顺序表类型
typedef struct
{
RedType r[MAXSIZE + 1]; // r[0]闲置或用作哨兵单元
int length; // 顺序表长度
}SqList;
// 打印顺序表
void print(SqList L)
{
int i;
for (i = 1; i <= L.length; i++)
printf("(%d, %d) ", L.r[i].key, L.r[i].otherinfo);
printf("\n\n");
}
// 对顺序表L作直接插入排序。
void InsertSort(SqList *L)
{
int i, j;
// 升序排序
for (i = 2; i <= (*L).length; ++i)
if ((*L).r[i].key < (*L).r[i - 1].key)
{
(*L).r[0] = (*L).r[i]; // 复制为哨兵
for (j = i - 1; (*L).r[0].key < (*L).r[j].key; --j)
(*L).r[j + 1] = (*L).r[j]; // 记录后移
(*L).r[j + 1] = (*L).r[0]; // 插入到正确位置
print(*L); // 打印线性表
}
}
int main()
{
RedType d[N] = {
{ 49, 1 }, { 38, 2 }, { 65, 3 }, { 97, 4 },
{ 76, 5 }, { 13, 6 }, { 27, 7 }, { 49, 8 }
};
SqList L;
int i;
int dt[T] = { 5, 3, 1 }; // 增量序列数组
// 给L.r赋值
for (i = 0; i < N; i++)
L.r[i + 1] = d[i];
L.length = N;
printf("排序前:\n");
print(L);
printf("\n直接插入排序的过程\n");
InsertSort(&L);
printf("\n直接插入排序后:\n");
print(L);
return 0;
}
二、 单链表
1. 单链表合并
/*【问题描述】
1、建立两个有序的单链表,表中元素的数据类型自己指定;
2、将建立的两个链表合并为一个新的有序的单链表;
3、输出显示已合并好的有序的单链表。
【输入形式】输入表1的元素个数,表1的元素值(逆序),同表1,输入表2的数据。
【输出形式】输出合并后的元素值。
【样例输入】 3 //表1元素个数
22 21 19 //表1的元素值(逆序)
4 //表2元素个数输出显示已合并好的有序的单链表
92 91 31 29 //表2的元素值(逆序)
【样例输出】 The current List is:
19,21,22,29,31,91,92
【样例说明】
【评分标准】*/
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct LNODE//创建链表节点类型的数据类型
{
int data;
struct LNODE *next;
}LNODE, *linklist;
int createlist(linklist &l,int n)//创建包含头节点的单链表
{
linklist p;
l=(linklist)malloc(sizeof(LNODE));
l->next=NULL;
for (int i=n;i>0;i--)
{
p=(linklist)malloc(sizeof(LNODE));
scanf("%d",&(p->data));
p->next=l->next;
l->next=p;
}
return 1;
}
int traverse_list(linklist l)//遍历单链表
{
linklist p;
p=l->next;
while (p!=NULL)
{
printf("%d",p->data);
p=p->next;
if(p)
printf(",");
}
return 1;
}
int merge_list(linklist &la,linklist &lb,linklist &lc)//将两个有序的单链表合并为一个
{
linklist pa,pb,pc;
pa=la->next;
pb=lb->next;
lc=pc=la;
while (pa&&pb)
{
if(pa->data<=pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
pc->next=pa?pa:pb;
free(lb);
return 1;
}
int main()
{
int n,m;
linklist la,lb,lc;
scanf("%d",&n);
createlist(la,n);
scanf("%d",&m);
createlist(lb,m);
merge_list(la,lb,lc);
printf("The current List is:\n");
traverse_list(lc);
return 1;
}
2. 单链表剔重
/*【问题描述】已知线性表中的元素以值的递增有序排列,并以单链表作存储结构。
试写一高效的算法,删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同),
同时释放被删结点空间,并分析你的算法的时间复杂度。
【输入形式】输入递增数字序列,以空格进行分隔
【输出形式】输出删除相同的多余元素后的线性表元素,元素之间以空格分隔
【样例输入】1 2 2 3
【样例输出】1 2 3
【样例说明】
【评分标准】*/
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct LNODE
{
int data;
struct LNODE *next;
}LNODE, *linklist;
int createlist(linklist &l,int n)//创建包含头节点的单链表
{
linklist p;
l=(linklist)malloc(sizeof(LNODE));
l->next=NULL;
p=(linklist)malloc(sizeof(LNODE));
while(scanf("%d",&(p->data))!=-1)
{
//p=(linklist)malloc(sizeof(LNODE));
//scanf("%d",&(p->data));
p->next=l->next;
l->next=p;
p=(linklist)malloc(sizeof(LNODE));
}
return 1;
}
int listdelete(linklist &l)
{
linklist p;
int j=0,n;
while(l->next!=NULL)
{
l=l->next;
n=l->data;
l=l->next;
if(n==l->data)
{
p=l->next;
l=l->next;
free(p);
//l->next=l->next;
}
}
}
int traverse_list(linklist l)//遍历单链表
{
linklist p;
p=l->next;
while (p!=NULL)
{
printf("%d ",p->data);
}
return 1;
}
int main()
{
linklist la;
createlist(la);
listdelete(la);
traverse_list(la);
//system("pause");
return 1;
}
三、 栈
1. 回文字符
/*【问题描述】1、用键盘输入一字符序列,存入一字符数组中;
2、利用堆栈判断其是否中心对称(回文数据),并输出结果。
【输入形式】 输入字符串,字符用小写的英文字符。
【输出形式】 输出1表示是回文,输出0表示不是回文。
【样例输入】 abcba
【样例输出】 1
int huiwendg(int *a,int *b,sqstack S)//原本想使用递归,后来没写出来!!!
{
int n=0;
n=stacklength(S);
if (n==0)
return -1;
if ((S.base+1)==S.top||(S.base+2)== S.top)
return 1;
else
return fundigui(S.base+1,S.top-1,S);
} */
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define STASIZE 50
#define CREMENT 5
typedef struct//定义顺序栈
{
int length;//栈的长度
char * base;
char * top;
int stacksize;//栈的最大空间大小
}sqstack;
int initstack (sqstack &S)//构造空栈
{
S.length=0;//栈的长度初始化为零
S.base=(char *)malloc(STASIZE * sizeof(char));//申请空间
if(!S.base)
exit(-1);
S.top=S.base;
S.stacksize=STASIZE;
return 1;
}
int push(sqstack &S,char e)//插入元素e到栈顶
{
if(S.top-S.base>=S.stacksize)
{
S.base=(char *)realloc(S.base,(S.stacksize+CREMENT) * sizeof(char));//空间不足需要再次分配
if(!S.base)
exit(-1);
S.top=S.base+S.stacksize;
S.stacksize+=CREMENT;
}
*S.top++=e;
S.length++;//栈的长度加1
return S.length;
}
int pop(sqstack &S,char &e)//删除栈顶元素e,并返回其值。
{
if(S.top==S.base)
return 0;
e=*--S.top;
S.length--;
return 1;
}
int stackempty(sqstack S)//判断栈是否为空
{
if(S.top==S.base)
return 1;
else
return 0;
}
int gettop(sqstack &S,char &e)//栈不为空时,返回栈顶元素。
{
if(S.top==S.base)
return 0;
e=*(S.top-1);
return 1;
}
int stacklength(sqstack S)//获得栈的长度。
{
int n=0;
while (S.top!=S.base)
{
S.top--;
n++;
}
S.top+=n;
return n;
}
/*使用顺序栈作为元素的存储结构,使用栈的长度,
利用头指针与尾指针向栈的中间移动(指针加1或减1),
先判断元素是否一样,再判断地址是否相遇*/
int huiwenxh(sqstack S)
{
if (S.length==0)
{
printf("0\n");
return 1;
}
if (S.length==1)
{
printf("1\n");
return 1;
}
S.top--;
if(*S.base!=*S.top)//栈顶与栈底元素不一样?
{
printf("0\n");
return 1;
}
else
{
while(!((S.base+1)==S.top||(S.base+2)== S.top))//判断是否到达栈的中间
{
S.top--;
S.base++;
if(*S.base!=*S.top)//栈顶与栈底元素不一样?
{
printf("0\n");
exit(-1);
}
}
printf("1\n");
return 1;
}
}
int main()
{
char c;
sqstack S;//构造指向空栈的指针
initstack (S);//构造空栈S
//printf("请输入字符串:\n");
while(1)
{
scanf("%c",&c);
if (c=='\n')
{ break; }
push(S,c);
}
huiwenxh(S);
//system("pause");
return 0;
}
2. 进制转换
/*【问题描述】1、用键盘输入任意一个十进制整数;
2、利用堆栈将其转换成R进制的数值,并输出结果。
【输入形式】 输入要转换的十进制数和要转换进制的基数(试验中只考虑2、8、16进制)。
【输出形式】 输出转换后的结果。
【样例输入】 92 //要转换的十进制数
16 //要转换进制的基数
【样例输出】 5C //转换后的16进制数*/
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define STASIZE 50
#define CREMENT 5
typedef struct//定义顺序栈
{
int * base;
int * top;
int stacksize;
}sqstack;
int initstack (sqstack &S)//构造空栈
{
S.base=(int *)malloc(STASIZE * sizeof(int));
if(!S.base)
exit(-1);
S.top=S.base;
S.stacksize=STASIZE;
return 1;
}
int push(sqstack &S,int e)//插入元素e到栈顶
{
if(S.top-S.base>=S.stacksize)
{
S.base=(int *)realloc(S.base,(S.stacksize+CREMENT) * sizeof(int));
if(!S.base)
exit(-1);
S.top=S.base+S.stacksize;
S.stacksize+=CREMENT;
}
*S.top++=e;
return 1;
}
int pop(sqstack &S,int &e)//删除栈顶元素e,并返回其值。
{
if(S.top==S.base)
return 0;
e=*--S.top;
return 1;
}
char gettop(sqstack &S,int &e)//栈不为空时,返回栈顶元素。
{
if(S.top==S.base)
return 0;
e=*(S.top-1);
return 1;
}
int stackempty(sqstack S)
{
if(S.top==S.base)
return 1;
else
return 0;
}
void conversion(int A,int B,sqstack &S)//进制之间转换
{
int n;
while(B)
{
push(S,B%A);
B=B/A;
}
while(!stackempty(S))//判断栈是否为空
{
pop(S,n);
switch (n)
{
case 10:printf("%s","A");break;
case 11:printf("%s","B");break;
case 12:printf("%s","C");break;
case 13:printf("%s","D");break;
case 14:printf("%s","E");break;
case 15:printf("%s","F");break;
default:printf("%d",n);break;
}
}
}
int main()
{
int m=0,n=0;
sqstack S;//构造指向空栈的指针
initstack(S);
//printf("请输入原数值:\n");
scanf("%d",&n);
//printf("请输入要转换的进制:\n");
scanf("%d",&m);
conversion(m,n,S);
//system("pause");
return 1;
}
3. 括号匹配
//括号匹配
#include <stdio.h>
#include <malloc.h>
typedef char SElemType; // 栈的元素类型
#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACKINCREMENT 2 // 存储空间分配增量
// 栈的顺序存储表示
typedef struct SqStack
{
SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
SElemType *top; // 栈顶指针
int stacksize; // 当前已分配的存储空间,以元素为单位
}SqStack; // 顺序栈
// 构造一个空栈S。
int InitStack(SqStack *S)// 为栈底分配一个指定大小的存储空间
{
(*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if (!(*S).base)
return 0; // 存储分配失败
(*S).top = (*S).base; // 栈底与栈顶相同表示一个空栈
(*S).stacksize = STACK_INIT_SIZE;
return 1;
}
// 若栈S为空栈(栈顶与栈底相同的),则返回1,否则返回0。
int StackEmpty(SqStack S)
{
if (S.top == S.base)
return 1;
else
return 0;
}
// 插入元素e为新的栈顶元素。
int Push(SqStack *S, SElemType e)
{
if ((*S).top - (*S).base >= (*S).stacksize) // 栈满,追加存储空间
{
(*S).base = (SElemType *)realloc((*S).base,
((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!(*S).base)
return 0; // 存储分配失败
(*S).top = (*S).base + (*S).stacksize;
(*S).stacksize += STACKINCREMENT;
}
*((*S).top)++ = e;
// 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左
return 1;
}
// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回1;否则返回0。
int Pop(SqStack *S, SElemType *e)
{
if ((*S).top == (*S).base)
return 0;
*e = *--(*S).top;// 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左
return 1;
}
// 对于输入的任意一个字符串,检验括号是否配对.
void check()
{
SqStack s;
SElemType ch[80], *p, e;
if (InitStack(&s)) // 初始化栈成功
{
printf("请输入表达式\n");
gets(ch);
p = ch;
while (*p) // 没到串尾
switch (*p)
{
case '(':
case '[':
Push(&s, *p++);
break; // 左括号入栈,且p++
case ')':
case ']':
if (!StackEmpty(s)) // 栈不空
{
Pop(&s, &e); // 弹出栈顶元素
if (*p == ')' && e != '(' || *p == ']' && e != '[')// 弹出的栈顶元素与*p不配对
{
printf("左右括号不配对\n");
return;
}
else
{
p++;
break; // 跳出switch语句
}
}
else // 栈空
{
printf("缺乏左括号\n");
return;
}
default: p++; // 其它字符不处理,指针向后移
}
if (StackEmpty(s)) // 字符串结束时栈空
printf("括号匹配\n");
else
printf("缺乏右括号\n");
}
}
int main()
{
check();
return 0;
}
四、 图
#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"
#define N 50
char visited[N];
int t=0;
typedef struct ANode//邻接表存储结构
{
char ad; //该弧所指向的顶点
struct ANode *next; //指向下一条弧的指针
}*AN;
typedef struct VNode
{
char vd; //顶点本身信息
AN first; //指向第一条依附该顶点的弧的指针
}VN [N];
typedef struct AVG
{
VN ves; //顶点数组
int vexnum, arcnum;//图的当前顶点数和弧数
}ALG;
void creategraph(ALG &G)//生成图的存储结构-邻接表
{
int i,j;
char wei,tou;//尾结点与头结点
AN p;//弧型指针
//printf("请输入有向图顶点个数:\n");
scanf("%d",&G.vexnum);
getchar();
//printf("输入顶点字符:\n"); //输入顶点建立顶点表
for(i=0; i<G.vexnum; i++)
{
scanf("%c", &G.ves[i].vd);
getchar();
G.ves[i].first=(struct ANode *)malloc(sizeof(struct ANode));
G.ves[i].first=NULL;
}
//printf("请输入有向图边的个数:\n");
scanf("%d",&G.arcnum);
getchar();
//printf("请输入有向图边的信息:\n");
//printf("起始点 终点\n");
for(i=0;i<G.arcnum;i++)//输入各边并构造邻接表
{
scanf("%c %c",&wei, &tou);
getchar();
for(j=0; j<G.vexnum; j++)
{
if(wei==G.ves[j].vd)
{
p=(struct ANode *)malloc(sizeof(struct ANode));
p->ad=tou;
p->next=G.ves[j].first;
G.ves[j].first=p;
break;
}
}
}
}
bool find(char s)
{
for(int m=0; m<t; m++)
{
if(visited[m]==s)
{ return false; }
}
return true;
}
void DFS(AN p, ALG G)
{
for(int j=0; j<G.vexnum; j++)
{
if(p->ad==G.ves[j].vd)
{
if(find(G.ves[j].vd)==true)
{
printf("%c", G.ves[j].vd);
visited[t++]=G.ves[j].vd;
}
if(G.ves[j].first!=NULL)
{ DFS(G.ves[j].first, G); }
}
}
}
void DFSTraverse(ALG G)
{
int i;
for(i=0; i<G.vexnum; i++)
{
if(find(G.ves[i].vd)==true)
{
printf("%c", G.ves[i].vd);
visited[t++]=G.ves[i].vd;
DFS(G.ves[i].first, G);
}
}
}
void BFSTraverse(ALG G)//对图做递归广度优先遍历
{
char wei,tou;//尾结点与头结点
AN p;//结点型指针
int i=0, j=0, k;
char s[N];
for(i; i<G.vexnum; i++)
{
s[j++]=G.ves[i].vd;
p=G.ves[i].first;
while(p)
{ s[j++]=p->ad;
p=p->next;
}
}
printf("%c", s[0]);
for(i=1; i<j; i++)
{
for(k=0; k<i; k++)
{
if(s[k]==s[i])
{ break; }
}
if(k==i)
{ printf("%c", s[i]); }
}
}/////////*/
int main()
{
ALG AG;
creategraph(AG);
//printf("\n\n------深度优先遍历\n\n");
DFSTraverse(AG);
printf("\n");
//printf("------广度优先遍历\n\n");
BFSTraverse(AG);
//system("pause");
return 0;
}
五、 树
1. 二叉树
/*二叉树的层次遍历
可以利用队列先进先出的特性,
首先访问根节点,把根节点压入队列中,
接着将根结点出队,
如果队列不为空,则循环执行下列动作,直到队列为空,
访问根结点的数据部分,再将根结点的左孩子与右孩子压入队列,
队列为空时有两种情况,一树为空,二树已访问完毕。*/
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define N 100
typedef struct bitnode///二叉树的相关数据结构
{
char data;
struct bitnode *lchild,*rchild;//左右孩子指针
}*BiTree;
typedef struct//线性队列
{
BiTree B[N];
int front,rear;
}Queue;
int createBiTree(BiTree &T)//按照先序序列递归构造一棵二叉树
{
char c;
scanf("%c",&c);//先读入一个字符
getchar();//再读入一个空格
if(c=='*')
T=NULL;
else
{
if(!(T=(struct bitnode *)malloc(sizeof(struct bitnode))))
exit (-1);
T->data=c;
createBiTree(T->lchild);
createBiTree(T->rchild);
}
return 1;
}
int pretra(BiTree T)//先序递归遍历二叉树
{
if(T)
{
printf("%c ",T->data);
pretra(T->lchild);
pretra(T->rchild);
return 1;
}
else
return 0;
}
int intra(BiTree T)//中序递归遍历二叉树
{
if(T)
{
intra(T->lchild);
printf("%c ",T->data);
intra(T->rchild);
return 1;
}
else
return 0;
}
int posttra(BiTree T)//后序递归遍历二叉树
{
if(T)
{
posttra(T->lchild);
posttra(T->rchild);
printf("%c ",T->data);
return 1;
}
else
return 0;
}
int InitQueue(Queue &Q)//构造一个空的队列Q
{
Q.front=0;
Q.rear=0;
return 1;
}
int EnQueue(Queue &Q,BiTree B)//入队
{
if(Q.rear==N)//队列已满
{
return 0;
}
Q.B[Q.rear]=B;
Q.rear++;
return 1;
}
int DeQueue(Queue &Q,BiTree &B)//出队
{
if(Q.rear==Q.front)//队列已空
{
return 0;
}
B=Q.B[Q.front];
Q.front++;
return 1;
}
void cengcitra(BiTree BT,Queue &Q)
{
BiTree T;
T=(struct bitnode*)malloc(sizeof(struct bitnode));
if(BT)
{
EnQueue(Q,BT);
while(Q.front!=Q.rear)
{
DeQueue(Q,T); //节点出队
printf("%c ", T->data);//访问出队的节点
if (T->lchild)
EnQueue(Q,T->lchild);//左儿子入队
if (T->rchild)
EnQueue(Q,T->rchild); //右儿子入队
}
}
}
int main()
{
Queue Q;//构造指向空队列的指针
InitQueue(Q);//创建队列Q
BiTree T;//构造指向空树的指针
//按先序输入树的结点
createBiTree(T);//创建二叉树T
pretra(T); //先序遍历结果
printf("\n");
intra(T); //中序遍历结果
printf("\n");
posttra(T); //后序遍历结果
printf("\n");
cengcitra(T,Q);//层次遍历结果
system("pause");
return 1;
}
2. 哈夫曼树
#include <stdio.h>
#include <limits.h>
#include <malloc.h>
#include <string.h>
typedef struct// 使用的结构体:
{
unsigned int weight;
unsigned int parent, lchild, rchild;
}HTNode, *HuffmanTree; //动态分配数组存储哈夫曼树
typedef char **HuffmanCode; //动态分配数组存储哈夫曼编码表
//实现代码:
int min1(HuffmanTree t, int i)//函数void select()调用
{
int j, flag;
unsigned int k = UINT_MAX; // 取k为不小于可能的值
for (j = 1; j <= i; j++)
if (t[j].weight < k && t[j].parent == 0)
k = t[j].weight, flag = j;
t[flag].parent = 1;
return flag;
}
void select(HuffmanTree t, int i, int *s1, int *s2)// s1为最小的两个值中序号小的那个
{
int j;
*s1 = min1(t, i);
*s2 = min1(t, i);
if (*s1 > *s2)
{
j = *s1;
*s1 = *s2;
*s2 = j;
}
}
void HuffmanCoding(HuffmanTree *HT, HuffmanCode *HC, int *w, int n)// w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的哈夫曼编码HC
{
int m, i, s1, s2, start;
unsigned c, f;
HuffmanTree p;
char *cd;
if (n <= 1)
return;
m = 2 * n - 1; //因为一颗有n个叶子结点的赫夫曼树共有2n-1个结点
*HT = (HuffmanTree)malloc((m + 1)*sizeof(HTNode)); // 0号单元未用
for (p = *HT + 1, i = 1; i <= n; ++i, ++p, ++w) //初始化各结点的权值
{
(*p).weight = *w;
(*p).parent = 0;
(*p).lchild = 0;
(*p).rchild = 0;
}
for (; i <= m; ++i, ++p) //初始化双亲位置
(*p).parent = 0;
for (i = n + 1; i <= m; ++i) // 建哈夫曼树
{
// 在HT[1 ~ i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
select(*HT, i - 1, &s1, &s2);
(*HT)[s1].parent = (*HT)[s2].parent = i;
(*HT)[i].lchild = s1;
(*HT)[i].rchild = s2;
(*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
}// 从叶子到根逆向求每个字符的哈夫曼编码
*HC = (HuffmanCode)malloc((n + 1)*sizeof(char*));// 分配n个字符编码的头指针向量([0]不用)
cd = (char*)malloc(n*sizeof(char)); // 分配求编码的工作空间
cd[n - 1] = '\0'; // 编码结束符
for (i = 1; i <= n; i++)// 逐个字符求哈夫曼编码
{
start = n - 1; // 编码结束符位置
for (c = i, f = (*HT)[i].parent; f != 0; c = f, f = (*HT)[f].parent)// 从叶子到根逆向求编码
if ((*HT)[f].lchild == c)
cd[--start] = '0';
else
cd[--start] = '1';
(*HC)[i] = (char*)malloc((n - start)*sizeof(char));// 为第i个字符编码分配空间
strncpy((*HC)[i], &cd[start]); // 从cd复制编码(串)到HC
}
free(cd); // 释放工作空间
}
int main()
{
HuffmanTree HT;
HuffmanCode HC;
int *w, n, i;
printf("请输入权值的个数(>1):");
scanf("%d", &n);
w = (int*)malloc(n*sizeof(int));
printf("请依次输入%d个权值(整型):\n", n);
for (i = 0; i <= n - 1; i++)
scanf("%d", w + i);
HuffmanCoding(&HT, &HC, w, n);
for (i = 1; i <= n; i++)
puts(HC[i]);
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析