一、     顺序表

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;

}

 

posted on 2022-10-07 20:34  逆凌  阅读(52)  评论(0编辑  收藏  举报