*/ --------------------------------------------------------------------------------------
*/ 出自: CSDN学生大本营http://student.csdn.net/
*/ 作者: 斯之不远 E-mail:sizhibuyuan@163.com QQ:1170927177
*/ 时间:
2011-3-24
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------
数据结构课程中写的学习例程,在此收集到一起。一般程序都不难也不大,并且所有例程均有较详细注释。中间有一个“哈夫曼编码”,程序较大,希望能给大家一点启示。以下所有程序均在VC++6.0开发环境中调试通过,运行正常。
数据结构与算法基本程序目录
一、 线性表及其操作
1 、 尾插法建立一个单链表,并按顺序输出
2 、 单链表的元素查找,按内容查找
3 、 元素插入操作
4 、 按内容元素删除操作
5 、 按位置删除元素
6 、 建立双向链表
7 、 单链表就地逆置
8 、 约瑟夫环问题
二、 栈及其操作
1 、 建立堆栈
2 、 进栈与出栈
3 、 栈的应用,括号匹配
三、 队及其操作
1 、 链队列的建立
2 、 入队和出队
3 、 循环队列建立
4 、 循环队列的入队和出队操作
四、 串及其操作
1 、 串的朴素匹配
五、 树(二叉树)及其操作
1 、 二叉排序树
2 、 哈夫曼编码
六、 排序
1 、 冒泡排序
2 、 直接选择排序法
一、线性表及其操作
//All copyright are preserved by cobby
/* 尾插法建立一个单链表,并按顺序输出 */
/* 尾插法建立一个单链表,并按顺序输出 */
#define NULL 0 /*
宏定义
*/
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
main()
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
l=(L)malloc(sizeof(L)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar(); // 此语句用来吸收键盘输入的回车符,没有其它含义
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(L)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
}
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
l=(L)malloc(sizeof(L)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar(); // 此语句用来吸收键盘输入的回车符,没有其它含义
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(L)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
}
//All copyright are preserved bycobby
/* 单链表的元素查找,按内容查找 */
#define NULL 0 /* 宏定义 */
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
main()
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
int n;
l=(L)malloc(sizeof(L)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(L)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
int n;
l=(L)malloc(sizeof(L)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(L)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
/*--------
以上为建立一个单链表
-------------*/
printf("/nInput a character you wanna find/n");
scanf("%c",&ch);
printf("/nthe character you wanna find is %c/n",ch);
q=l->next; /*q 移至头结点的后一个元素,即实际第一个数据点 */
n=1; // 位置计数器
while(q!=NULL) /* 若 q 不为空,即该结点存在 */
{
if(q->c==ch) /* 字符匹配 */
printf("character found in position %d/n",n);
q=q->next; /* 移至下一个元素继续查找 */
n++;
}
}
//All copyright are preserved bycobby
/* 元素插入操作 */
#define NULL 0 /*
宏定义
*/
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}Node,*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}Node,*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
main()
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
int pos,n;
l=(L)malloc(sizeof(Node)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(Node)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
int pos,n;
l=(L)malloc(sizeof(Node)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(Node)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
/*
以上为建立一个单链表
*/
printf("Input the character and its position, such as s,3/n/n");
scanf("%c,%d",&ch,&pos);
q=l;
n=1;
while(n!=pos&&q->next!=NULL) /* 未找到插入位置,且后面还有元素 */
{
q=q->next;
n++;
}
/* 退出循环后,要么找到插入位置,要么表已到最后,输入的插入位置过大 */
scanf("%c,%d",&ch,&pos);
q=l;
n=1;
while(n!=pos&&q->next!=NULL) /* 未找到插入位置,且后面还有元素 */
{
q=q->next;
n++;
}
/* 退出循环后,要么找到插入位置,要么表已到最后,输入的插入位置过大 */
if(n<pos) /*
表已读完,仍未找到插入位置
*/
printf("/n/nincorrect position, insert failed/n/n");
else /* 找到插入位置 */
{
/* 将进行插入操作 */
p=(L)malloc(sizeof(Node)); /* 给新输入的数据分配内存空间 */
p->c=ch;
p->next=q->next;
q->next=p;
}
printf("/n/nincorrect position, insert failed/n/n");
else /* 找到插入位置 */
{
/* 将进行插入操作 */
p=(L)malloc(sizeof(Node)); /* 给新输入的数据分配内存空间 */
p->c=ch;
p->next=q->next;
q->next=p;
}
/*
操作完成,然后输出新表
*/
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
}
//All copyright are preserved bycobby
/* 按内容元素删除操作 */
#include<malloc.h>
#include<stdio.h>
#include<stdio.h>
#define NULL 0 /*
宏定义
*/
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}Node,*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}Node,*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
main()
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
int n;
l=(L)malloc(sizeof(Node)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(Node)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
int n;
l=(L)malloc(sizeof(Node)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(Node)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
/*
以上为建立单链表
*/
printf("input the character you wanna delete/n/n");
scanf("%c",&ch);
printf("the element you wanna delete is %c/n/n",ch);
q=l->next;
p=l;
n=1;
scanf("%c",&ch);
printf("the element you wanna delete is %c/n/n",ch);
q=l->next;
p=l;
n=1;
while(q!=NULL&&q->c!=ch)
{
p=q;
q=q->next;
n++;
}
/* 退出循环时可能找到指定元素,也可能表读完,需要进一步判断 */
if(q==NULL)
printf("element not found, delete failed/n/n");
else
p->next=q->next;
{
p=q;
q=q->next;
n++;
}
/* 退出循环时可能找到指定元素,也可能表读完,需要进一步判断 */
if(q==NULL)
printf("element not found, delete failed/n/n");
else
p->next=q->next;
q=l->next; /*
输入整个链表前,先将
q
移到链表头,
l
一般不动
*/
while(q!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
}
while(q!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
}
//All copyright are preserved bycobby
/* 按位置删除元素 */
/* 按位置删除元素 */
#define NULL 0 /*
宏定义
*/
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}Node,*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}Node,*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
main()
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
int pos,n;
l=(L)malloc(sizeof(Node)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(Node)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
{
L l,p,q; /* 用指针类型定义三个结点类型的指针 */
char ch;
int pos,n;
l=(L)malloc(sizeof(Node)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(Node)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
/*
以上为建立单链表
*/
printf("Input the position/n");
scanf("%d",&pos);
p=l;
n=1;
while(p->next!=NULL&&n!=pos)
{
p=p->next;
n++;
}
/* 退出循环后,可能找到删除的元素位置,可能表读完,需要进一步判断 */
if(n==pos) /* 删除位置找到,删除该位置上的元素 */
{
p->next=p->next->next;
//free(p);
}
else
printf("incorrect position, delete failed/n");
scanf("%d",&pos);
p=l;
n=1;
while(p->next!=NULL&&n!=pos)
{
p=p->next;
n++;
}
/* 退出循环后,可能找到删除的元素位置,可能表读完,需要进一步判断 */
if(n==pos) /* 删除位置找到,删除该位置上的元素 */
{
p->next=p->next->next;
//free(p);
}
else
printf("incorrect position, delete failed/n");
q=l; /*
输入整个链表前,先将
q
移到链表头,
l
一般不动
*/
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
}
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
}
//
建立双向链表
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<malloc.h>
#include<stdlib.h>
#define NULL 0
typedef struct dlnode
{
char ch;
struct dlnode *pri,*next;
}dnode,*dl;
{
char ch;
struct dlnode *pri,*next;
}dnode,*dl;
main()
{
dl l,p,q;
char c;
l=(dl)malloc(sizeof(dnode));
l->ch='/0';
l->next=NULL;
l->pri=NULL;
q=l;
{
dl l,p,q;
char c;
l=(dl)malloc(sizeof(dnode));
l->ch='/0';
l->next=NULL;
l->pri=NULL;
q=l;
printf("
输入字符建立双向链表
/n");
scanf("%c",&c);
getchar();
while(c!='!')
{
p=(dl)malloc(sizeof(dnode));
p->ch=c;
p->pri=q;
p->next=NULL;
q->next=p;
q=p;
scanf("%c",&c);
getchar();
}
q=l;
while(q->next!=NULL)
{
q=q->next;
printf("%c-->",q->ch);
}
printf("/n");
while(q->pri!=NULL)
{
printf("%c-->",q->ch);
q=q->pri;
}
printf("/n");
}
scanf("%c",&c);
getchar();
while(c!='!')
{
p=(dl)malloc(sizeof(dnode));
p->ch=c;
p->pri=q;
p->next=NULL;
q->next=p;
q=p;
scanf("%c",&c);
getchar();
}
q=l;
while(q->next!=NULL)
{
q=q->next;
printf("%c-->",q->ch);
}
printf("/n");
while(q->pri!=NULL)
{
printf("%c-->",q->ch);
q=q->pri;
}
printf("/n");
}
//
单链表就地逆置
#define NULL 0 /*
宏定义
*/
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}Node,*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
typedef struct node /* 定义结点类型的数据结构 */
{
char c; /* 数据域,类型为字符型 */
struct node *next; /* 指针域,类型为本结构体类型 */
}Node,*L; /* 类型重定义,即 Node 和 *L 和 struct node 等价 */
main()
{
L l,p,q,r; /* 用指针类型定义三个结点类型的指针 */
char ch;
l=(L)malloc(sizeof(Node)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(Node)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
printf("/n");
{
L l,p,q,r; /* 用指针类型定义三个结点类型的指针 */
char ch;
l=(L)malloc(sizeof(Node)); /* 分配内存空间 */
l->c='/0'; /* 为头结点的数据域赋值,值为空 */
l->next=NULL; /* 指明下一个结点目前不存在 */
q=l; /*q 为游动指针,链表结点的连结要用 */
printf("Input a character:/n");
scanf("%c",&ch);
getchar();
while(ch!='!') /* 输入 ! 表示输入结束 */
{
p=(L)malloc(sizeof(Node)); /* 为新输入的数据分配内存空间 */
p->c=ch;
p->next=NULL; /* 新输入的结点在链表的最后,即它的后面没有其它元素 */
q->next=p; /*q 用于将上一个元素链接至当前新元素 */
q=p; /*q 自己移到当前最后一个元素,以备继续链接所用 */
scanf("%c",&ch);
getchar();
}
q=l; /* 输入整个链表前,先将 q 移到链表头, l 一般不动 */
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
printf("/n");
//
以上完成了单链表的创建
q=l->next;
p=q->next;
r=p->next;
q->next=NULL;
while(r!=NULL)
{
p->next=q;
q=p;
p=r;
if(r->next!=NULL) //r 后面还有结点,则逆置继续
r=r->next;
else
break;
}
r->next=q;
l->next=r; // 头结点指向最后一个结点
q=l->next;
p=q->next;
r=p->next;
q->next=NULL;
while(r!=NULL)
{
p->next=q;
q=p;
p=r;
if(r->next!=NULL) //r 后面还有结点,则逆置继续
r=r->next;
else
break;
}
r->next=q;
l->next=r; // 头结点指向最后一个结点
q=l; /*
输入整个链表前,先将
q
移到链表头,
l
一般不动
*/
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
printf("/n");
}
while(q->next!=NULL) /* 若 q 所指向的元素后面还有其它元素,则将该元素的数据输出 */
{
printf("%c-->",q->next->c); /*q->next->c 表示 q 所指向的下一个元素的数据 */
q=q->next; /* 完成该元素的输出后, q 移至下一个元素重复输出操作 */
}
printf("/n");
}
// 约瑟夫环问题
#include<stdio.h>
#include<malloc.h>
#include<malloc.h>
typedef struct lnode
{
int num;
struct lnode *next;
}node,*L;
{
int num;
struct lnode *next;
}node,*L;
main()
{
int amount,start,circle,n,c;
L p,l,q;
{
int amount,start,circle,n,c;
L p,l,q;
printf("
一共有几个人围成一圈?
/n");
scanf("%d",&amount);
getchar();
printf(" 从第几个开始计数? /n");
scanf("%d",&start);
getchar();
printf(" 每几人一次循环? /n");
scanf("%d",&circle);
getchar();
scanf("%d",&amount);
getchar();
printf(" 从第几个开始计数? /n");
scanf("%d",&start);
getchar();
printf(" 每几人一次循环? /n");
scanf("%d",&circle);
getchar();
l=(L)malloc(sizeof(node)); //
头结点
l->next=NULL;
l->num=0;
q=l;
n=0;
l->next=NULL;
l->num=0;
q=l;
n=0;
while(n++<amount)
{
p=(L)malloc(sizeof(node));
p->next=NULL;
p->num=n;
q->next=p;
q=p;
}
q->next=l->next; // 形成循环链表
{
p=(L)malloc(sizeof(node));
p->next=NULL;
p->num=n;
q->next=p;
q=p;
}
q->next=l->next; // 形成循环链表
//
以上完成了单向循环链表的建立
p=l->next;
q=l;
n=1;
while(n++<start)
{
p=p->next;
q=q->next;
}
// 退出循环时 p,q 分别位于指定位置
p=l->next;
q=l;
n=1;
while(n++<start)
{
p=p->next;
q=q->next;
}
// 退出循环时 p,q 分别位于指定位置
//
接下去进行周期性结点删除,直到链表只余一个结点为止
n=1; //n 计算被删除的结点的数量,当 n=amount-1 时删除结束
while(n++<amount)
{
c=1; //c 作为循环临时变量
while(c++<circle)
{
p=p->next;
q=q->next;
}
// 删除当前 p 指向的结点
printf(" 删除结点 %d/t",p->num);
q->next=p->next;
p=p->next;
}
printf("/n 最后剩下 %d/n",p->num);
}
n=1; //n 计算被删除的结点的数量,当 n=amount-1 时删除结束
while(n++<amount)
{
c=1; //c 作为循环临时变量
while(c++<circle)
{
p=p->next;
q=q->next;
}
// 删除当前 p 指向的结点
printf(" 删除结点 %d/t",p->num);
q->next=p->next;
p=p->next;
}
printf("/n 最后剩下 %d/n",p->num);
}
二、栈及其操作
//All copyright are preserved bycobby
/* 建立堆栈 */
//All copyright are preserved bycobby
/* 建立堆栈 */
#include<stdio.h>
#include<malloc.h>
#define NULL 0
#include<malloc.h>
#define NULL 0
typedef struct node
{
char ch;
struct node *next;
}Snode,*stack;
{
char ch;
struct node *next;
}Snode,*stack;
main()
{
stack s,top,p;
char ch;
s=(stack)malloc(sizeof(Snode));
s->ch='/0';
s->next=NULL; /* 建立栈底指针 */
top=s;
scanf("%c",&ch);
getchar();
while(ch!='!')
{
p=(stack)malloc(sizeof(Snode));
p->ch=ch;
p->next=top;
top=p;
scanf("%c",&ch);
getchar();
}
{
stack s,top,p;
char ch;
s=(stack)malloc(sizeof(Snode));
s->ch='/0';
s->next=NULL; /* 建立栈底指针 */
top=s;
scanf("%c",&ch);
getchar();
while(ch!='!')
{
p=(stack)malloc(sizeof(Snode));
p->ch=ch;
p->next=top;
top=p;
scanf("%c",&ch);
getchar();
}
while(top->next!=NULL)
{
printf("%c-->",top->ch);
top=top->next;
}
printf("/n");
}
{
printf("%c-->",top->ch);
top=top->next;
}
printf("/n");
}
//All copyright are preserved bycobby
/* 进栈与出栈 */
#include<stdio.h>
#include<malloc.h>
#define NULL 0
#include<malloc.h>
#define NULL 0
typedef struct node
{
char ch;
struct node *next;
}Snode,*stack;
{
char ch;
struct node *next;
}Snode,*stack;
main()
{
stack s,top,p;
char ch;
int choice;
s=(stack)malloc(sizeof(Snode));
s->ch='!';
s->next=NULL; /* 建立栈底指针 */
top=s;
scanf("%c",&ch);
getchar();
while(ch!='!')
{
p=(stack)malloc(sizeof(Snode));
p->ch=ch;
p->next=top;
top=p;
scanf("%c",&ch);
getchar();
}
{
stack s,top,p;
char ch;
int choice;
s=(stack)malloc(sizeof(Snode));
s->ch='!';
s->next=NULL; /* 建立栈底指针 */
top=s;
scanf("%c",&ch);
getchar();
while(ch!='!')
{
p=(stack)malloc(sizeof(Snode));
p->ch=ch;
p->next=top;
top=p;
scanf("%c",&ch);
getchar();
}
while(p->next!=NULL) //
此处
p
可用
top
代替
{
printf("%c-->",p->ch);
p=p->next;
}
printf("/n");
{
printf("%c-->",p->ch);
p=p->next;
}
printf("/n");
/*
以上建立了一个堆栈
*/
printf("
进栈或出栈?输入
“1”
为进栈,输入
“2”
为出栈,其它则退出程序
/n");
scanf("%d",&choice);
getchar();
while(choice==1||choice==2) // 若不是输入 1 或 2 ,则不做任何操作
{
if(choice==1)
{
/* 进栈 */
printf("/n 输入要入栈的元素 /n");
scanf("%c",&ch);
getchar();
p=(stack)malloc(sizeof(Snode));
p->ch=ch;
p->next=top;
top=p;
}
else if(choice==2)
{
if(top->next!=NULL)
top=top->next;
else
{
printf(" 栈已清空 /n");
exit();
}
/* 出栈 */
}
//printf("%c-->",top->ch);
p=top;
while(p->next!=NULL)
{
printf("%c-->",p->ch);
p=p->next;
}
printf("/n");
printf(" 进栈或出栈?输入 “1” 为进栈,输入 “2” 为出栈,其它则退出程序 /n");
scanf("%d",&choice);
getchar();
}
}
scanf("%d",&choice);
getchar();
while(choice==1||choice==2) // 若不是输入 1 或 2 ,则不做任何操作
{
if(choice==1)
{
/* 进栈 */
printf("/n 输入要入栈的元素 /n");
scanf("%c",&ch);
getchar();
p=(stack)malloc(sizeof(Snode));
p->ch=ch;
p->next=top;
top=p;
}
else if(choice==2)
{
if(top->next!=NULL)
top=top->next;
else
{
printf(" 栈已清空 /n");
exit();
}
/* 出栈 */
}
//printf("%c-->",top->ch);
p=top;
while(p->next!=NULL)
{
printf("%c-->",p->ch);
p=p->next;
}
printf("/n");
printf(" 进栈或出栈?输入 “1” 为进栈,输入 “2” 为出栈,其它则退出程序 /n");
scanf("%d",&choice);
getchar();
}
}
//All copyright are preserved bycobby
// 栈的应用,括号匹配
#include<stdio.h>
#include<malloc.h>
#define NULL 0
typedef struct node
{
char ch;
struct node *next;
}snode,*stack;
main()
{
stack s,top,p;
char *string,ch[100]="";
{
stack s,top,p;
char *string,ch[100]="";
s=(stack)malloc(sizeof(snode)); //
建立栈底元素
s->ch='/0';
s->next=NULL;
top=s;
s->ch='/0';
s->next=NULL;
top=s;
printf("
输入一个含括号的四则运算表达式:
/n");
scanf("%s",ch);
string=ch;
scanf("%s",ch);
string=ch;
while(*string!='/0')
{
if(*string=='('||*string=='['||*string=='{') // 遇到左括号,入栈
{
p=(stack)malloc(sizeof(snode));
p->ch=*string;
p->next=top;
top=p;
}
else if(*string==')'||*string==']'||*string=='}') // 遇到右括号
{
if(*string==')')
if(top->ch=='(') // 括号匹配
top=top->next;
else
{
printf(" 小括号不匹配 ");
exit(0);
}
else if(*string==']')
if(top->ch=='[') // 括号匹配
top=top->next;
else
{
printf(" 中括号不匹配 ");
exit(0);
}
else
if(top->ch=='{') // 括号匹配
top=top->next;
else
{
printf(" 大括号不匹配 ");
exit(0);
}
}
string++;
}
if(top->ch!='/0')
printf(" 多出左括号 %c/n",top->ch);
}
{
if(*string=='('||*string=='['||*string=='{') // 遇到左括号,入栈
{
p=(stack)malloc(sizeof(snode));
p->ch=*string;
p->next=top;
top=p;
}
else if(*string==')'||*string==']'||*string=='}') // 遇到右括号
{
if(*string==')')
if(top->ch=='(') // 括号匹配
top=top->next;
else
{
printf(" 小括号不匹配 ");
exit(0);
}
else if(*string==']')
if(top->ch=='[') // 括号匹配
top=top->next;
else
{
printf(" 中括号不匹配 ");
exit(0);
}
else
if(top->ch=='{') // 括号匹配
top=top->next;
else
{
printf(" 大括号不匹配 ");
exit(0);
}
}
string++;
}
if(top->ch!='/0')
printf(" 多出左括号 %c/n",top->ch);
}
三、队及其操作
//All copyright are preserved bycobby
// 链队列的建立
//All copyright are preserved bycobby
// 链队列的建立
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define NULL 0
#include<stdlib.h>
#include<malloc.h>
#define NULL 0
typedef struct node //
队列结点的基本数据结构,即队列中每个结点的类型
{
char c;
struct node *next;
}qnode,*basic_node;
{
char c;
struct node *next;
}qnode,*basic_node;
typedef struct //
队列实际上由头、尾两个结点指针构成,即头指针和尾指针唯一确定时,队列也被唯一确定
{
qnode *head;
qnode *rear;
}queue,*Q;
{
qnode *head;
qnode *rear;
}queue,*Q;
main()
{
Q q; // 定义队列,结构体变量 q 中含有头指针 head 和尾指针 rear ,所以 q 是一个完整的队列(只不过队列为空)
// 事实上,任何由 Q 定义的结构体变量都是一个独立完整的队列
basic_node p,l; //basic_node 是基本结点类型,即是独立的结点,它是组成队列的基本元素。
// 基本结点 p,l 和队列 q 的关系可由下图表示:
// (q->head)--->p--->l--->p--->l--->……--->p--->l--->(q->rear)
char ch;
{
Q q; // 定义队列,结构体变量 q 中含有头指针 head 和尾指针 rear ,所以 q 是一个完整的队列(只不过队列为空)
// 事实上,任何由 Q 定义的结构体变量都是一个独立完整的队列
basic_node p,l; //basic_node 是基本结点类型,即是独立的结点,它是组成队列的基本元素。
// 基本结点 p,l 和队列 q 的关系可由下图表示:
// (q->head)--->p--->l--->p--->l--->……--->p--->l--->(q->rear)
char ch;
q=(Q)malloc(sizeof(queue));
q->head=NULL; // 初始化时队列为空
q->rear=NULL;
q->head=NULL; // 初始化时队列为空
q->rear=NULL;
printf("
输入队列元素
:/n");
scanf("%c",&ch);
getchar();
while(ch!='!')
{
p=(qnode*)malloc(sizeof(qnode));
p->c=ch;
p->next=NULL; // 新来的元素一定在队列的最后,它的后面没有其它元素
if(q->head==NULL)
{
q->head=p; // 第一个元素入队时,队头指针指向它
l=q->head; //l 指向第一个元素
}
l->next=p; // 使前一个元素指向当前入队的新元素
l=p; //l 移动到当前新元素,以备用下次入队操作
q->rear=p; // 修改队尾指针,使其总是指向当前最后一个队列元素
scanf("%c",&ch);
getchar();
}
l=q->head;
while(l!=NULL)
{
printf("%c<--",l->c);
l=l->next;
}
printf("/n");
printf(" 头指针指向元素为 %c/t 尾指针指向元素为 %c/n",q->head->c,q->rear->c );
}
scanf("%c",&ch);
getchar();
while(ch!='!')
{
p=(qnode*)malloc(sizeof(qnode));
p->c=ch;
p->next=NULL; // 新来的元素一定在队列的最后,它的后面没有其它元素
if(q->head==NULL)
{
q->head=p; // 第一个元素入队时,队头指针指向它
l=q->head; //l 指向第一个元素
}
l->next=p; // 使前一个元素指向当前入队的新元素
l=p; //l 移动到当前新元素,以备用下次入队操作
q->rear=p; // 修改队尾指针,使其总是指向当前最后一个队列元素
scanf("%c",&ch);
getchar();
}
l=q->head;
while(l!=NULL)
{
printf("%c<--",l->c);
l=l->next;
}
printf("/n");
printf(" 头指针指向元素为 %c/t 尾指针指向元素为 %c/n",q->head->c,q->rear->c );
}
//All copyright are preserved bycobby
//
入队和出队
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define NULL 0
#include<stdlib.h>
#include<malloc.h>
#define NULL 0
typedef struct node //
队列结点的基本数据结构,即队列中每个结点的类型
{
char c;
struct node *next;
}qnode,*basic_node;
{
char c;
struct node *next;
}qnode,*basic_node;
typedef struct //
队列实际上由头、尾两个结点指针构成,即头指针和尾指针唯一确定时,队列也被唯一确定
{
qnode *head;
qnode *rear;
}queue,*Q;
{
qnode *head;
qnode *rear;
}queue,*Q;
main()
{
Q q; // 定义队列,结构体变量 q 中含有头指针 head 和尾指针 rear ,所以 q 是一个完整的队列(只不过队列为空)
// 事实上,任何由 Q 定义的结构体变量都是一个独立完整的队列
basic_node p,l; //basic_node 是基本结点类型,即是独立的结点,它是组成队列的基本元素。
// 基本结点 p,l 和队列 q 的关系可由下图表示:
// (q->head)--->p--->l--->p--->l--->……--->p--->l--->(q->rear)
char ch;
int choice;
{
Q q; // 定义队列,结构体变量 q 中含有头指针 head 和尾指针 rear ,所以 q 是一个完整的队列(只不过队列为空)
// 事实上,任何由 Q 定义的结构体变量都是一个独立完整的队列
basic_node p,l; //basic_node 是基本结点类型,即是独立的结点,它是组成队列的基本元素。
// 基本结点 p,l 和队列 q 的关系可由下图表示:
// (q->head)--->p--->l--->p--->l--->……--->p--->l--->(q->rear)
char ch;
int choice;
q=(Q)malloc(sizeof(queue));
q->head=NULL; // 初始化时队列为空
q->rear=NULL;
q->head=NULL; // 初始化时队列为空
q->rear=NULL;
printf("
输入队列元素
:/n");
scanf("%c",&ch);
getchar();
while(ch!='!')
{
p=(qnode*)malloc(sizeof(qnode));
p->c=ch;
p->next=NULL; // 新来的元素一定在队列的最后,它的后面没有其它元素
if(q->head==NULL)
{
q->head=p; // 第一个元素入队时,队头指针指向它
l=q->head; //l 指向第一个元素
}
l->next=p; // 使前一个元素指向当前入队的新元素
l=p; //l 移动到当前新元素,以备用下次入队操作
q->rear=p; // 修改队尾指针,使其总是指向当前最后一个队列元素
scanf("%c",&ch);
getchar();
}
l=q->head;
while(l!=NULL)
{
printf("%c<--",l->c);
l=l->next;
}
printf("/n");
printf(" 头指针指向元素为 %c/t 尾指针指向元素为 %c/n",q->head->c,q->rear->c );
scanf("%c",&ch);
getchar();
while(ch!='!')
{
p=(qnode*)malloc(sizeof(qnode));
p->c=ch;
p->next=NULL; // 新来的元素一定在队列的最后,它的后面没有其它元素
if(q->head==NULL)
{
q->head=p; // 第一个元素入队时,队头指针指向它
l=q->head; //l 指向第一个元素
}
l->next=p; // 使前一个元素指向当前入队的新元素
l=p; //l 移动到当前新元素,以备用下次入队操作
q->rear=p; // 修改队尾指针,使其总是指向当前最后一个队列元素
scanf("%c",&ch);
getchar();
}
l=q->head;
while(l!=NULL)
{
printf("%c<--",l->c);
l=l->next;
}
printf("/n");
printf(" 头指针指向元素为 %c/t 尾指针指向元素为 %c/n",q->head->c,q->rear->c );
// 以上建立了一个队列
printf("
输入
1
进行入队,输入
2
进行出队
:/n");
scanf("%d",&choice);
getchar();
scanf("%d",&choice);
getchar();
if(choice==1)
{
printf("/n 输入要入队的元素 :/n");
scanf("%c",&ch);
getchar();
p=(qnode*)malloc(sizeof(qnode)); // 给新入队的元素分配内存空间
p->c=ch;
p->next=NULL; // 新元素为最后一个元素
q->rear->next=p; // 原来最后一个元素指向新入队的元素
q->rear=p; // 修改队尾指针,使其指向当前最后一个元素
}
else if(choice==2)
q->head=q->head->next;
else
exit(0);
{
printf("/n 输入要入队的元素 :/n");
scanf("%c",&ch);
getchar();
p=(qnode*)malloc(sizeof(qnode)); // 给新入队的元素分配内存空间
p->c=ch;
p->next=NULL; // 新元素为最后一个元素
q->rear->next=p; // 原来最后一个元素指向新入队的元素
q->rear=p; // 修改队尾指针,使其指向当前最后一个元素
}
else if(choice==2)
q->head=q->head->next;
else
exit(0);
l=q->head;
while(l!=NULL)
{
printf("%c<--",l->c);
l=l->next;
}
printf("/n");
printf(" 头指针指向元素为 %c/t 尾指针指向元素为 %c/n",q->head->c,q->rear->c );
}
while(l!=NULL)
{
printf("%c<--",l->c);
l=l->next;
}
printf("/n");
printf(" 头指针指向元素为 %c/t 尾指针指向元素为 %c/n",q->head->c,q->rear->c );
}
//All copyright are preserved bycobby
// 循环队列建立
#include<stdio.h>
#include<malloc.h>
#define MAX 8
#include<malloc.h>
#define MAX 8
typedef struct
{
char c[MAX]; // 循环队列是顺序队列的一种,它的核心就是一个数组
int front; // 整形变量,作为头指针用
int rear; // 整形变量,作为尾指针用
}queue;
{
char c[MAX]; // 循环队列是顺序队列的一种,它的核心就是一个数组
int front; // 整形变量,作为头指针用
int rear; // 整形变量,作为尾指针用
}queue;
main()
{
queue *q;
char ch;
int i;
q=(queue*)malloc(sizeof(queue)); // 生成一个空循环队列
for(i=0;i<MAX;i++)
q->c[i]='/0';
q->front=0;
q->rear=0;
{
queue *q;
char ch;
int i;
q=(queue*)malloc(sizeof(queue)); // 生成一个空循环队列
for(i=0;i<MAX;i++)
q->c[i]='/0';
q->front=0;
q->rear=0;
printf("
输入要入队的元素
:/n");
scanf("%c",&ch);
getchar();
while(ch!='!')
{
if((q->rear+1)%MAX==q->front) // 若队列已满
{
printf(" 队列已满,无法入队 /n");
break;
}
else
{
q->c[q->rear]=ch; //rear 指向当前可入队的数组元素位置
q->rear=(q->rear+1)%MAX; // 修改尾指针,向后移动一个位置
// 注意,不能简单使用 q->rear++ ,不然会导致队列溢出
}
scanf("%c",&ch);
getchar();
}
scanf("%c",&ch);
getchar();
while(ch!='!')
{
if((q->rear+1)%MAX==q->front) // 若队列已满
{
printf(" 队列已满,无法入队 /n");
break;
}
else
{
q->c[q->rear]=ch; //rear 指向当前可入队的数组元素位置
q->rear=(q->rear+1)%MAX; // 修改尾指针,向后移动一个位置
// 注意,不能简单使用 q->rear++ ,不然会导致队列溢出
}
scanf("%c",&ch);
getchar();
}
for(i=q->front;i<q->rear;i=(i+1)%MAX) //
能够用
for
循环,说明了顺序队列和链式队列的区别
printf("%c<--",q->c[i]);
printf("/n");
}
printf("%c<--",q->c[i]);
printf("/n");
}
//All copyright are preserved bycobby
// 循环队列的入队和出队操作
#include<stdio.h>
#include<malloc.h>
#define MAX 8
#include<malloc.h>
#define MAX 8
typedef structd
{
char c[MAX]; // 循环队列是顺序队列的一种,它的核心就是一个数组
int front; // 整形变量,作为头指针用
int rear; // 整形变量,作为尾指针用
}queue;
{
char c[MAX]; // 循环队列是顺序队列的一种,它的核心就是一个数组
int front; // 整形变量,作为头指针用
int rear; // 整形变量,作为尾指针用
}queue;
main()
{
queue *q;
char ch;
int i,choice;
q=(queue*)malloc(sizeof(queue)); // 生成一个空循环队列
for(i=0;i<MAX;i++)
q->c[i]='/0';
q->front=0;
q->rear=0;
{
queue *q;
char ch;
int i,choice;
q=(queue*)malloc(sizeof(queue)); // 生成一个空循环队列
for(i=0;i<MAX;i++)
q->c[i]='/0';
q->front=0;
q->rear=0;
printf("
输入要入队的元素
:/n");
scanf("%c",&ch);
getchar();
while(ch!='!')
{
if((q->rear+1)%MAX==q->front) // 若队列已满
{
printf(" 队列已满,无法入队 /n");
break;
}
else
{
q->c[q->rear]=ch; //rear 指向当前可入队的数组元素位置
q->rear=(q->rear+1)%MAX; // 修改尾指针,向后移动一个位置
// 注意,不能简单使用 q->rear++ ,不然会导致队列溢出
}
scanf("%c",&ch);
getchar();
}
scanf("%c",&ch);
getchar();
while(ch!='!')
{
if((q->rear+1)%MAX==q->front) // 若队列已满
{
printf(" 队列已满,无法入队 /n");
break;
}
else
{
q->c[q->rear]=ch; //rear 指向当前可入队的数组元素位置
q->rear=(q->rear+1)%MAX; // 修改尾指针,向后移动一个位置
// 注意,不能简单使用 q->rear++ ,不然会导致队列溢出
}
scanf("%c",&ch);
getchar();
}
printf("
头指针指向元素为
%d/t
尾指针指向元素为
%d/n",q->front,q->rear);
for(i=q->front;i<q->rear;i=(i+1)%MAX) //
能够用
for
循环,说明了顺序队列和链式队列的区别
printf("%c-->",q->c[i]);
printf("/n");
printf("%c-->",q->c[i]);
printf("/n");
//
以上建立了一个循环队列
printf(" 输入 1 入队,输入 2 出队 :/n");
scanf("%d",&choice);
getchar();
printf(" 输入 1 入队,输入 2 出队 :/n");
scanf("%d",&choice);
getchar();
while(choice==1||choice==2)
{
if(choice==1)
{
printf(" 输入要入队的元素 /n");
scanf("%c",&ch);
getchar();
if((q->rear+1)%MAX==q->front) // 若队列已满
{
printf(" 队列已满,无法入队 /n");
break;
}
else
{
q->c[q->rear]=ch; //rear 指向当前可入队的数组元素位置
q->rear=(q->rear+1)%MAX; // 修改尾指针,向后移动一个位置
// 注意,不能简单使用 q->rear++ ,不然会导致队列溢出
}
}
else if(choice==2)
{
if((q->front+1)%MAX!=q->rear) // 队非空
{
q->c[q->front]='/0'; // 删除元素
q->front=(q->front+1)%MAX; // 修改队头指针
}
else
{
printf(" 队已清空 /n");
break;
}
}
{
if(choice==1)
{
printf(" 输入要入队的元素 /n");
scanf("%c",&ch);
getchar();
if((q->rear+1)%MAX==q->front) // 若队列已满
{
printf(" 队列已满,无法入队 /n");
break;
}
else
{
q->c[q->rear]=ch; //rear 指向当前可入队的数组元素位置
q->rear=(q->rear+1)%MAX; // 修改尾指针,向后移动一个位置
// 注意,不能简单使用 q->rear++ ,不然会导致队列溢出
}
}
else if(choice==2)
{
if((q->front+1)%MAX!=q->rear) // 队非空
{
q->c[q->front]='/0'; // 删除元素
q->front=(q->front+1)%MAX; // 修改队头指针
}
else
{
printf(" 队已清空 /n");
break;
}
}
if(q->rear>q->front) //
尾指针在头指针的右边
{
for(i=q->front;i<q->rear;i=(i+1)%MAX) // 能够用 for 循环,说明了顺序队列和链式队列的区别
printf("%c<--",q->c[i]);
printf("/n");
}
else // 尾指针在头指针的左边
{
for(i=q->front;i<(q->rear+MAX);i++) // 能够用 for 循环,说明了顺序队列和链式队列的区别
printf("%c<--",q->c[i%MAX]);
printf("/n");
}
printf(" 头指针指向元素为 %d/t 尾指针指向元素为 %d/n",q->front,q->rear);
{
for(i=q->front;i<q->rear;i=(i+1)%MAX) // 能够用 for 循环,说明了顺序队列和链式队列的区别
printf("%c<--",q->c[i]);
printf("/n");
}
else // 尾指针在头指针的左边
{
for(i=q->front;i<(q->rear+MAX);i++) // 能够用 for 循环,说明了顺序队列和链式队列的区别
printf("%c<--",q->c[i%MAX]);
printf("/n");
}
printf(" 头指针指向元素为 %d/t 尾指针指向元素为 %d/n",q->front,q->rear);
printf("
输入
1
入队,输入
2
出队
:/n");
scanf("%d",&choice);
getchar();
}
}
scanf("%d",&choice);
getchar();
}
}
四、串及其操作
// 串的朴素匹配
// 串的朴素匹配
#include<stdio.h>
main()
{
char str1[100],str2[100],*p;
int i=0,j=0,len_str1=0,len_str2=0,num=0;
printf(" 输入母串 :/n");
scanf("%s",str1);
getchar();
{
char str1[100],str2[100],*p;
int i=0,j=0,len_str1=0,len_str2=0,num=0;
printf(" 输入母串 :/n");
scanf("%s",str1);
getchar();
printf("%
输入子串
:/n");
scanf("%s",str2);
getchar();
scanf("%s",str2);
getchar();
p=str1;
while(*p!='/0') // 获取母串长度
{
len_str1++;
p++;
}
while(*p!='/0') // 获取母串长度
{
len_str1++;
p++;
}
p=str2; //
获取子串长度
while(*p!='/0')
{
len_str2++;
p++;
}
for(i=0;i<len_str1;i++) //i 为母串下标
{
for(j=0;j<len_str2;j++) //j 为子串下标
{
num++;
if(str1[i+j]!=str2[j])
break; // 若当前字符不匹配,则指针向母串下一个字符移动
}
if(j==len_str2)
{
printf(" 子串在母串中的位置为 %d/n",i+1);
//break; // 若子串在母串中多次出现,则全部找到其位置。若恢复 break 语句则只找出最前的一个匹配子串
}
}
printf(" 母串长度为 %d, 子串长度为 %d/n 核心语句执行次数为 %d/n",len_str1,len_str2,num);
}
while(*p!='/0')
{
len_str2++;
p++;
}
for(i=0;i<len_str1;i++) //i 为母串下标
{
for(j=0;j<len_str2;j++) //j 为子串下标
{
num++;
if(str1[i+j]!=str2[j])
break; // 若当前字符不匹配,则指针向母串下一个字符移动
}
if(j==len_str2)
{
printf(" 子串在母串中的位置为 %d/n",i+1);
//break; // 若子串在母串中多次出现,则全部找到其位置。若恢复 break 语句则只找出最前的一个匹配子串
}
}
printf(" 母串长度为 %d, 子串长度为 %d/n 核心语句执行次数为 %d/n",len_str1,len_str2,num);
}
五、树(二叉树)及其操作
// 二叉排序树
// 二叉排序树
#include<stdio.h>
#include<stdlib.h>
#include<stdlib.h>
typedef struct tnode
{
int num;
struct tnode *Lchild,*Rchild;
}Tnode,*Btree;
{
int num;
struct tnode *Lchild,*Rchild;
}Tnode,*Btree;
typedef struct snode
{
int num;
Btree r;
struct snode *next;
}Snode,*stack;
{
int num;
Btree r;
struct snode *next;
}Snode,*stack;
Btree root;
void describe_tree() //
交互式显示哈夫曼树
{
Btree t;
stack s,top,temp;
int choice;
{
Btree t;
stack s,top,temp;
int choice;
s=(stack)malloc(sizeof(Snode));
s->num=0;
s->next=NULL;
s->r=NULL;
top=s;
t=root;//t 指向哈夫曼树的根结点
s->num=0;
s->next=NULL;
s->r=NULL;
top=s;
t=root;//t 指向哈夫曼树的根结点
temp=(stack)malloc(sizeof(Snode)); //
分配新栈结点
temp->num=t->num;
temp->next=top; // 结点入栈
temp->r=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
temp->num=t->num;
temp->next=top; // 结点入栈
temp->r=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf("
输入
1
往左子树,输入
2
往右子树,输入
3
返回父结点,其它输入退出程序
/n");
scanf("%d",&choice);
getchar();
while(choice==1||choice==2||choice==3)
{
if(choice==1) // 往左子树
{
if(t->Lchild!=NULL)
{
t=t->Lchild;
temp=(stack)malloc(sizeof(Snode)); // 分配新栈结点
// 新结点入栈
temp->num=t->num;
temp->next=top; // 结点入栈
temp->r=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf(" 值为 %d/n",t->num);
}
else // 左子树不存在,当前结点已经是叶子结点
printf(" 无左孩子! /n");
}
else if(choice==2) // 往右子树
{
if(t->Rchild!=NULL)
{
t=t->Rchild;
temp=(stack)malloc(sizeof(Snode)); // 分配新栈结点
// 新结点入栈
temp->num=t->num;
temp->next=top; // 结点入栈
temp->r=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf(" 值为 %d/n",t->num);
}
else // 右子树不存在,当前结点已经是叶子结点
printf(" 无右孩子! /n");
}
else if(choice==3) // 返回父结点
{
if(top->next!=s) // 栈非空
{
top=top->next;
t=top->r;
printf(" 值为 %d/n",t->num);
}
else
printf(" 已经在根结点了! /n");
}
scanf("%d",&choice);
getchar();
while(choice==1||choice==2||choice==3)
{
if(choice==1) // 往左子树
{
if(t->Lchild!=NULL)
{
t=t->Lchild;
temp=(stack)malloc(sizeof(Snode)); // 分配新栈结点
// 新结点入栈
temp->num=t->num;
temp->next=top; // 结点入栈
temp->r=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf(" 值为 %d/n",t->num);
}
else // 左子树不存在,当前结点已经是叶子结点
printf(" 无左孩子! /n");
}
else if(choice==2) // 往右子树
{
if(t->Rchild!=NULL)
{
t=t->Rchild;
temp=(stack)malloc(sizeof(Snode)); // 分配新栈结点
// 新结点入栈
temp->num=t->num;
temp->next=top; // 结点入栈
temp->r=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf(" 值为 %d/n",t->num);
}
else // 右子树不存在,当前结点已经是叶子结点
printf(" 无右孩子! /n");
}
else if(choice==3) // 返回父结点
{
if(top->next!=s) // 栈非空
{
top=top->next;
t=top->r;
printf(" 值为 %d/n",t->num);
}
else
printf(" 已经在根结点了! /n");
}
scanf("%d",&choice);
getchar();
}
}
getchar();
}
}
void inorder(Btree r) //
中序递归遍历
{
if(r!=NULL)
{
inorder(r->Lchild);
printf(" %d <",r->num);
inorder(r->Rchild);
}
}
{
if(r!=NULL)
{
inorder(r->Lchild);
printf(" %d <",r->num);
inorder(r->Rchild);
}
}
main()
{
int array[100],n=0,i,choice;
Btree p,q;
{
int array[100],n=0,i,choice;
Btree p,q;
for(i=0;i<100;i++)
array[i]=0;
array[i]=0;
printf("
输入若干个整数
,
结束用
/"0/"
表示
/n");
scanf("%d",&array[n++]);
getchar();
while(array[n-1]!=0)
scanf("%d",&array[n++]);
scanf("%d",&array[n++]);
getchar();
while(array[n-1]!=0)
scanf("%d",&array[n++]);
n=0;
if(array[n]!=0)
{
root=(Btree)malloc(sizeof(Tnode)); // 建立二叉排序树的根结点
root->num=array[n];
root->Lchild=NULL;
root->Rchild=NULL;
n++;
}
else
exit(0);
if(array[n]!=0)
{
root=(Btree)malloc(sizeof(Tnode)); // 建立二叉排序树的根结点
root->num=array[n];
root->Lchild=NULL;
root->Rchild=NULL;
n++;
}
else
exit(0);
while(array[n]!=0)
{
p=(Btree)malloc(sizeof(Tnode)); // 依次给每个整数分配结点
p->num=array[n];
p->Lchild=NULL;
p->Rchild=NULL;
{
p=(Btree)malloc(sizeof(Tnode)); // 依次给每个整数分配结点
p->num=array[n];
p->Lchild=NULL;
p->Rchild=NULL;
//
分配完结点后,要插入到二叉树中合适的位置
q=root; //q 初始化到根结点
while(q!=NULL)
{
if(q->num<p->num) // 若新结点的值大于根结点的值,则往右子树
{
if(q->Rchild!=NULL) // 当前结点有右孩子,则指针移向右孩子继续比较
q=q->Rchild;
else // 当前结点没有右孩子,则新结点为当前结点的右孩子
{
q->Rchild=p;
break;
}
}
else
{
if(q->Lchild!=NULL) // 当前结点有左孩子,则指针移向左孩子继续比较
q=q->Lchild;
else // 当前结点没有左孩子,则新结点为当前结点的左孩子
{
q->Lchild=p;
break;
}
}
}
n++;
}
// 建立二叉排序树完毕
// 对其进行中序遍历
printf("/n 哈夫曼树构造完成,是否查看哈夫曼树,输入 1 查看,其它输入跳过 ");
scanf("%d",&choice);
getchar();
if(choice==1)
describe_tree();
inorder(root);
printf("/n");
}
q=root; //q 初始化到根结点
while(q!=NULL)
{
if(q->num<p->num) // 若新结点的值大于根结点的值,则往右子树
{
if(q->Rchild!=NULL) // 当前结点有右孩子,则指针移向右孩子继续比较
q=q->Rchild;
else // 当前结点没有右孩子,则新结点为当前结点的右孩子
{
q->Rchild=p;
break;
}
}
else
{
if(q->Lchild!=NULL) // 当前结点有左孩子,则指针移向左孩子继续比较
q=q->Lchild;
else // 当前结点没有左孩子,则新结点为当前结点的左孩子
{
q->Lchild=p;
break;
}
}
}
n++;
}
// 建立二叉排序树完毕
// 对其进行中序遍历
printf("/n 哈夫曼树构造完成,是否查看哈夫曼树,输入 1 查看,其它输入跳过 ");
scanf("%d",&choice);
getchar();
if(choice==1)
describe_tree();
inorder(root);
printf("/n");
}
哈夫曼算法程序太大,一个贴放不下,下面两个贴均为哈夫曼编码程序
.
//2005/4/28
//All Copyright Are Reserved By cobby
// 哈夫曼编码
//2005/4/28
//All Copyright Are Reserved By cobby
// 哈夫曼编码
#include<stdio.h>
#include<malloc.h>
#include<math.h>
#define NULL 0
#include<malloc.h>
#include<math.h>
#define NULL 0
typedef struct huff_code_node //
存储编码的链表
{
char ch; // 编码对应的字符
char code[100]; // 字符对应的哈夫曼码
struct huff_code_node *next;
}hnode,*huff;
{
char ch; // 编码对应的字符
char code[100]; // 字符对应的哈夫曼码
struct huff_code_node *next;
}hnode,*huff;
typedef struct tree_Node //
二叉树结点
{
char ch; // 字符内容
int amount; // 字符在字符串中出现的次数
struct tree_Node *left,*right; // 指向左子树与右子树
}tnode,*bt;
{
char ch; // 字符内容
int amount; // 字符在字符串中出现的次数
struct tree_Node *left,*right; // 指向左子树与右子树
}tnode,*bt;
typedef struct list_node //
链表结点
{
char ch; // 存储字符串中的字符
int amount; // 字符在字符串中出现的次数
tnode *son; // 链表结点带有二叉子树的根结点指针
struct list_node *next; // 指向链表中下一个结点
}Node,*L;
{
char ch; // 存储字符串中的字符
int amount; // 字符在字符串中出现的次数
tnode *son; // 链表结点带有二叉子树的根结点指针
struct list_node *next; // 指向链表中下一个结点
}Node,*L;
typedef struct stack_node
{
char ch; // 存储字符
int amount; // 出现次数
bt son; // 指向二叉树的某结点
struct stack_node *next;
}snode,*stack;
{
char ch; // 存储字符
int amount; // 出现次数
bt son; // 指向二叉树的某结点
struct stack_node *next;
}snode,*stack;
char t[200],*str,*c; // 用于存储和处理输入的字符串
bt root=NULL; // 哈夫曼树
L l,p,q,new_node; // 链表结点
huff hlist; // 计算得到的编码表
int char_num; // 输入的不同字符数量
int char_amount; // 输入的所有字符数量
int code_sum; // 哈夫曼编码总长
void initial() // 初始化操作
{
l=(Node*)malloc(sizeof(Node)); // 建立空链表
l->ch='/0';
l->amount=0;
l->son=NULL;
l->next=NULL;
str=t; //
将字符串指针指向字符串的第一个位置
// 键盘输入字符串
printf(" 输入字符串进行哈夫曼编码 :/n");
scanf("%s",str);
getchar();
}
// 键盘输入字符串
printf(" 输入字符串进行哈夫曼编码 :/n");
scanf("%s",str);
getchar();
}
void pull_in_list()
{
int exist; // 表示当前字符是否存在于链表中, 0 为不存在, 1 为已存在
int n; // 计算输入不同字符的数量,计算后赋值给全局变量 char_num
int m; // 计算输入所有字符的数量,计算后赋值给全局变量 char_amount
c=str; //c 指向第一个字符
while(*c!='/0') // 若字符串未读完
{
exist=0;
p=l; //p 指向链表头结点
// 寻找该字符是否已经在链表中
while(p->next!=NULL) // 若链表非空
{
p=p->next;
if(p->ch==*c) // 若当前字符已经在链表中
{
exist=1;
p->amount++; // 字符出现次数加 1
break;
}
}
{
int exist; // 表示当前字符是否存在于链表中, 0 为不存在, 1 为已存在
int n; // 计算输入不同字符的数量,计算后赋值给全局变量 char_num
int m; // 计算输入所有字符的数量,计算后赋值给全局变量 char_amount
c=str; //c 指向第一个字符
while(*c!='/0') // 若字符串未读完
{
exist=0;
p=l; //p 指向链表头结点
// 寻找该字符是否已经在链表中
while(p->next!=NULL) // 若链表非空
{
p=p->next;
if(p->ch==*c) // 若当前字符已经在链表中
{
exist=1;
p->amount++; // 字符出现次数加 1
break;
}
}
if(exist==0) //
若当前字符不存在于链表中,则分配一个结点入表
{
new_node=(Node*)malloc(sizeof(Node));
new_node->ch=*c;
new_node->amount=1;
new_node->next=NULL;
new_node->son=NULL;
p->next=new_node;
p=new_node;
}
c++; // 读下一个字符
}
{
new_node=(Node*)malloc(sizeof(Node));
new_node->ch=*c;
new_node->amount=1;
new_node->next=NULL;
new_node->son=NULL;
p->next=new_node;
p=new_node;
}
c++; // 读下一个字符
}
printf("
统计结果
:/n");
p=l;
n=0;
m=0;
while(p->next!=NULL)
{
n++;
p=p->next;
m+=p->amount;
printf("%c——%d/n",p->ch,p->amount);
}
char_num=n;
char_amount=m;
printf(" 一共有 %d 种字符输入,字符总数 %d/n",char_num,char_amount);
}
p=l;
n=0;
m=0;
while(p->next!=NULL)
{
n++;
p=p->next;
m+=p->amount;
printf("%c——%d/n",p->ch,p->amount);
}
char_num=n;
char_amount=m;
printf(" 一共有 %d 种字符输入,字符总数 %d/n",char_num,char_amount);
}
int list_element_amount() //
计算链表中结点的数量(不包括头结点)
{
L temp; // 定义临时指针
int n=0; // 结点数量
temp=l;
while(temp->next!=NULL) // 后面还有结点
{
n++;
temp=temp->next;
}
return n;
}
{
L temp; // 定义临时指针
int n=0; // 结点数量
temp=l;
while(temp->next!=NULL) // 后面还有结点
{
n++;
temp=temp->next;
}
return n;
}
bt create() //
建立最优二叉树
{
//=========================================
// 这些变量用于寻找最小结点
L min1_pos,min2_pos,t,min_pri;
bt min1_son,min2_son;
int min1,min2;
char min1_c,min2_c;
//=========================================
{
//=========================================
// 这些变量用于寻找最小结点
L min1_pos,min2_pos,t,min_pri;
bt min1_son,min2_son;
int min1,min2;
char min1_c,min2_c;
//=========================================
//=========================================
// 这些变量用于构造二叉子树
bt left,right,root;
//==========================================
// 这些变量用于构造二叉子树
bt left,right,root;
//==========================================
//==========================================
// 这些变量用于将二叉子树信息插入链表
L made,temp_p;
//============================================
// 这些变量用于将二叉子树信息插入链表
L made,temp_p;
//============================================
while(list_element_amount()>=2) //
若表中还有两个或以上结点,则归并继续
{
// 选择次数值最小的两个结点
{
// 选择次数值最小的两个结点
//============================================================================
// 先寻找第一个小结点
t=l->next;
min1=t->amount; // 将第一个结点的次数值赋给 min1
min1_pos=t; // 将第一个结点的位置指针赋给 min1_pos
min1_c=t->ch; // 将第一个结点的字符赋值给 min1_c
min1_son=t->son; // 将第一个结点的二叉指针赋值给 min1_son
min_pri=l; //min_pri 始终指向最小结点的前驱,以方便删除最小结点
// 先寻找第一个小结点
t=l->next;
min1=t->amount; // 将第一个结点的次数值赋给 min1
min1_pos=t; // 将第一个结点的位置指针赋给 min1_pos
min1_c=t->ch; // 将第一个结点的字符赋值给 min1_c
min1_son=t->son; // 将第一个结点的二叉指针赋值给 min1_son
min_pri=l; //min_pri 始终指向最小结点的前驱,以方便删除最小结点
while(t->next!=NULL)
{
t=t->next;
if(min1>t->amount) // 发现更小的结点
{
min1=t->amount; // 将当前结点的次数值赋给 min1
min1_pos=t; // 将当前结点的位置指针赋给 min1_pos
min1_c=t->ch; // 将当前结点的字符赋值给 min1_c
min1_son=t->son; // 将当前结点的二叉指针赋值给 min1_son
}
}// 退出本循环时,最小结点的信息找出,将该结点删除
{
t=t->next;
if(min1>t->amount) // 发现更小的结点
{
min1=t->amount; // 将当前结点的次数值赋给 min1
min1_pos=t; // 将当前结点的位置指针赋给 min1_pos
min1_c=t->ch; // 将当前结点的字符赋值给 min1_c
min1_son=t->son; // 将当前结点的二叉指针赋值给 min1_son
}
}// 退出本循环时,最小结点的信息找出,将该结点删除
min_pri=l;
while(min_pri->next!=min1_pos)
min_pri=min_pri->next;
// 退出循环时 min_pri 指向 min1_pos 的前驱
min_pri->next=min1_pos->next; // 删除结点 min1_pos
// 寻找第一个小结点完成
//=================================================================
while(min_pri->next!=min1_pos)
min_pri=min_pri->next;
// 退出循环时 min_pri 指向 min1_pos 的前驱
min_pri->next=min1_pos->next; // 删除结点 min1_pos
// 寻找第一个小结点完成
//=================================================================
//=================================================================
// 先寻找第二个小结点
t=l->next;
min2=t->amount; // 将第二个结点的次数值赋给 min2
min2_pos=t; // 将第二个结点的位置指针赋给 min2_pos
min2_c=t->ch;
min2_son=t->son;
min_pri=l; //min_pri 始终指向最小结点的前驱,以方便删除最小结点
// 先寻找第二个小结点
t=l->next;
min2=t->amount; // 将第二个结点的次数值赋给 min2
min2_pos=t; // 将第二个结点的位置指针赋给 min2_pos
min2_c=t->ch;
min2_son=t->son;
min_pri=l; //min_pri 始终指向最小结点的前驱,以方便删除最小结点
while(t->next!=NULL)
{
t=t->next;
if(min2>t->amount) // 发现更小的结点
{
min2=t->amount; // 将当前结点的次数值赋给 min2
min2_pos=t; // 将当前结点的位置指针赋给 min2_pos
min2_c=t->ch;
min2_son=t->son;
}
}// 退出本循环时,最小结点的信息找出,将该结点删除
{
t=t->next;
if(min2>t->amount) // 发现更小的结点
{
min2=t->amount; // 将当前结点的次数值赋给 min2
min2_pos=t; // 将当前结点的位置指针赋给 min2_pos
min2_c=t->ch;
min2_son=t->son;
}
}// 退出本循环时,最小结点的信息找出,将该结点删除
min_pri=l;
while(min_pri->next!=min2_pos)
min_pri=min_pri->next;
// 退出循环时 min_pri 指向 min1_pos 的前驱
min_pri->next=min2_pos->next; // 删除结点 min2_pos
// 寻找第二个小结点完成
//=================================================================
while(min_pri->next!=min2_pos)
min_pri=min_pri->next;
// 退出循环时 min_pri 指向 min1_pos 的前驱
min_pri->next=min2_pos->next; // 删除结点 min2_pos
// 寻找第二个小结点完成
//=================================================================
//==================================================================
// 两个最小结点找到,由这对结点级成一个二叉子树,将根结点插入链表中
if(min1_son==NULL) // 该结点无二叉子树指针,则须新分配一个二叉树结点
{
left=(bt)malloc(sizeof(tnode)); // 产生左孩子
left->amount=min1; // 次数值复制
left->ch=min1_c; // 字符复制
left->left=NULL;
left->right=NULL;
}
else // 该结点为计算产生的结点,它已指向一个二叉子树
left=min1_son; //left 直接指向已经生成的二叉子树的根结点
if(min2_son==NULL) //
该结点无二叉子树指针,则须新分配一个二叉树结点
{
right=(bt)malloc(sizeof(tnode)); // 产生右孩子
right->amount=min2; // 次数值复制
right->ch=min2_c; // 字符复制
right->left=NULL;
right->right=NULL;
}
else
right=min2_son; //left 直接指向已经生成的二叉子树的根结点
{
right=(bt)malloc(sizeof(tnode)); // 产生右孩子
right->amount=min2; // 次数值复制
right->ch=min2_c; // 字符复制
right->left=NULL;
right->right=NULL;
}
else
right=min2_son; //left 直接指向已经生成的二叉子树的根结点
root=(bt)malloc(sizeof(tnode));
root->amount=min1+min2;
root->ch='/0'; // 对于计算产生的树结点,字符均为空
root->left=left;
root->right=right;
// 二叉子树完成
root->amount=min1+min2;
root->ch='/0'; // 对于计算产生的树结点,字符均为空
root->left=left;
root->right=right;
// 二叉子树完成
//
生成一个对应上面已产生二叉子树地址的链表结点
made=(L)malloc(sizeof(Node));
made->amount=root->amount;
made->ch=root->ch;
made->next=NULL;
made->son=root;
made=(L)malloc(sizeof(Node));
made->amount=root->amount;
made->ch=root->ch;
made->next=NULL;
made->son=root;
//
将生成的链表结点插入链表中
temp_p=l;
while(temp_p->next!=NULL)
temp_p=temp_p->next;
// 退出循环时 temp_p 指向链表最后一个结点
temp_p->next=made; // 将生成的结点插入链表
}
temp_p=l;
while(temp_p->next!=NULL)
temp_p=temp_p->next;
// 退出循环时 temp_p 指向链表最后一个结点
temp_p->next=made; // 将生成的结点插入链表
}
temp_p=l->next;
return temp_p->son;
}
return temp_p->son;
}
void encoding() //
根据建立的哈夫曼树编码
{
stack code,top,temp,readcode;
bt r;
huff temp_huff,hp;
char huff[100]=""; // 用于存储当前字符的哈夫曼编码串
int i,j,n=0;
{
stack code,top,temp,readcode;
bt r;
huff temp_huff,hp;
char huff[100]=""; // 用于存储当前字符的哈夫曼编码串
int i,j,n=0;
hlist=(hnode*)malloc(sizeof(hnode));
hlist->ch='/0';
for(i=0;i<100;i++)
hlist->code[i]='/0';
hlist->next=NULL;
hp=hlist;
hlist->ch='/0';
for(i=0;i<100;i++)
hlist->code[i]='/0';
hlist->next=NULL;
hp=hlist;
//
建立空栈
code=(stack)malloc(sizeof(snode));
code->amount=0;
code->ch='/0';
code->next=NULL;
code->son=NULL; // 栈的头结点指向树的根结点
top=code;
code=(stack)malloc(sizeof(snode));
code->amount=0;
code->ch='/0';
code->next=NULL;
code->son=NULL; // 栈的头结点指向树的根结点
top=code;
r=root;
temp=(stack)malloc(sizeof(snode)); // 给哈夫曼树的根结点分配栈结点
temp->amount=r->amount;
temp->ch='0';
temp->next=top;
temp->son=r;
top=temp;
while(r!=NULL) // 当前结点存在
{
if(r->left!=NULL&&r->left->amount!=-1) // 当前结点有左孩子
{
r=r->left; //r 转向左孩子
r->amount=-1;
temp=(stack)malloc(sizeof(snode)); // 给哈夫曼树的根结点分配栈结点
temp->amount=r->amount;
temp->ch='0';
temp->next=top;
temp->son=r;
top=temp;
while(r!=NULL) // 当前结点存在
{
if(r->left!=NULL&&r->left->amount!=-1) // 当前结点有左孩子
{
r=r->left; //r 转向左孩子
r->amount=-1;
temp=(stack)malloc(sizeof(snode)); //
给左孩子分配栈结点
temp->amount=r->amount;
temp->ch='0';
temp->next=top;
temp->son=r;
top=temp;
}
else if(r->right!=NULL&&r->right->amount!=-1) // 当前结点有右孩子
{
r=r->right; //r 转向右孩子
r->amount=-1;
temp->amount=r->amount;
temp->ch='0';
temp->next=top;
temp->son=r;
top=temp;
}
else if(r->right!=NULL&&r->right->amount!=-1) // 当前结点有右孩子
{
r=r->right; //r 转向右孩子
r->amount=-1;
temp=(stack)malloc(sizeof(snode)); //
给右孩子分配栈结点
temp->amount=r->amount;
temp->ch='1';
temp->next=top;
temp->son=r;
top=temp;
}
else // 无未访问的孩子结点
{
if(r->left==NULL&&r->right==NULL) // 当前结点为叶子结点
{
for(i=0;i<100;i++) // 对哈夫曼编码数组初始化
huff[i]='/0';
temp->amount=r->amount;
temp->ch='1';
temp->next=top;
temp->son=r;
top=temp;
}
else // 无未访问的孩子结点
{
if(r->left==NULL&&r->right==NULL) // 当前结点为叶子结点
{
for(i=0;i<100;i++) // 对哈夫曼编码数组初始化
huff[i]='/0';
//
先输出该叶子结点的编码
printf(" 字符 %c, 编码为 :",r->ch);
readcode=top;
i=0;
printf(" 字符 %c, 编码为 :",r->ch);
readcode=top;
i=0;
while(readcode!=code)
{
huff[i++]=readcode->ch; // 将栈元素倒置入哈夫曼编码数组中
readcode=readcode->next;
}
temp_huff=(hnode*)malloc(sizeof(hnode)); // 为当前字符及其编码创建结点
temp_huff->ch=r->ch; // 存储编码的原字符
for(j=0;j<100;j++) // 初始化编码串数组
temp_huff->code[j]='/0';
{
huff[i++]=readcode->ch; // 将栈元素倒置入哈夫曼编码数组中
readcode=readcode->next;
}
temp_huff=(hnode*)malloc(sizeof(hnode)); // 为当前字符及其编码创建结点
temp_huff->ch=r->ch; // 存储编码的原字符
for(j=0;j<100;j++) // 初始化编码串数组
temp_huff->code[j]='/0';
j=0;
for(i=i-2;i>=0;i--) //
依次读出哈夫曼编码数组中的编码串
{
printf("%c",huff[i]);
temp_huff->code[j++]=huff[i];
}
temp_huff->next=NULL;
hp->next=temp_huff;
hp=temp_huff;
{
printf("%c",huff[i]);
temp_huff->code[j++]=huff[i];
}
temp_huff->next=NULL;
hp->next=temp_huff;
hp=temp_huff;
printf("/t/t");
if(++n%2==0)
printf("/n");
}
if(++n%2==0)
printf("/n");
}
if(top->next!=code) //
若栈非空
{
top=top->next;
r=top->son;
}
else
break;
}
}
}
{
top=top->next;
r=top->son;
}
else
break;
}
}
}
void describe_tree() //
交互式显示哈夫曼树
{
bt t;
stack s,top,temp;
int choice;
{
bt t;
stack s,top,temp;
int choice;
s=(stack)malloc(sizeof(snode));
s->amount=0;
s->ch='/0';
s->next=NULL;
s->son=NULL;
top=s;
t=root;//t 指向哈夫曼树的根结点
s->amount=0;
s->ch='/0';
s->next=NULL;
s->son=NULL;
top=s;
t=root;//t 指向哈夫曼树的根结点
temp=(stack)malloc(sizeof(snode)); //
分配新栈结点
temp->amount=t->amount;
temp->ch=t->ch;
temp->next=top; // 结点入栈
temp->son=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
temp->amount=t->amount;
temp->ch=t->ch;
temp->next=top; // 结点入栈
temp->son=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf("
输入
1
往左子树,输入
2
往右子树,输入
3
返回父结点,输入
4
退出程序,其它输入无效
/n");
scanf("%d",&choice);
getchar();
while(choice==1||choice==2||choice==3)
{
if(choice==1) // 往左子树
{
if(t->left!=NULL)
{
t=t->left;
temp=(stack)malloc(sizeof(snode)); // 分配新栈结点
// 新结点入栈
temp->amount=t->amount;
temp->ch=t->ch;
temp->next=top; // 结点入栈
temp->son=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf("%c,%d/n",t->ch,t->amount);
}
else // 左子树不存在,当前结点已经是叶子结点
printf(" 无左孩子! /n");
}
else if(choice==2) // 往右子树
{
if(t->right!=NULL)
{
t=t->right;
temp=(stack)malloc(sizeof(snode)); // 分配新栈结点
// 新结点入栈
temp->amount=t->amount;
temp->ch=t->ch;
temp->next=top; // 结点入栈
temp->son=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf("%c,%d/n",t->ch,t->amount);
}
else // 右子树不存在,当前结点已经是叶子结点
printf(" 无右孩子! /n");
}
else if(choice==3) // 返回父结点
{
if(top->next!=s) // 栈非空
{
top=top->next;
t=top->son;
printf("%c,%d/n",t->ch,t->amount);
}
else
printf(" 已经在根结点了! /n");
}
//else if(choice==4) // 退出程序
// exit(0);
scanf("%d",&choice);
getchar();
while(choice==1||choice==2||choice==3)
{
if(choice==1) // 往左子树
{
if(t->left!=NULL)
{
t=t->left;
temp=(stack)malloc(sizeof(snode)); // 分配新栈结点
// 新结点入栈
temp->amount=t->amount;
temp->ch=t->ch;
temp->next=top; // 结点入栈
temp->son=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf("%c,%d/n",t->ch,t->amount);
}
else // 左子树不存在,当前结点已经是叶子结点
printf(" 无左孩子! /n");
}
else if(choice==2) // 往右子树
{
if(t->right!=NULL)
{
t=t->right;
temp=(stack)malloc(sizeof(snode)); // 分配新栈结点
// 新结点入栈
temp->amount=t->amount;
temp->ch=t->ch;
temp->next=top; // 结点入栈
temp->son=t; // 将当前二叉树结点指针给栈顶结点
top=temp; // 修改栈顶指针
printf("%c,%d/n",t->ch,t->amount);
}
else // 右子树不存在,当前结点已经是叶子结点
printf(" 无右孩子! /n");
}
else if(choice==3) // 返回父结点
{
if(top->next!=s) // 栈非空
{
top=top->next;
t=top->son;
printf("%c,%d/n",t->ch,t->amount);
}
else
printf(" 已经在根结点了! /n");
}
//else if(choice==4) // 退出程序
// exit(0);
scanf("%d",&choice);
getchar();
}
}
getchar();
}
}
void codeoutput() // 输出原始字符串的哈夫曼编码串
{
huff hp;
//char *s;
int i;
c=str; //c 指向原始字符串 str 的首位置
printf("/n/n 原始字符串为 :%s/n 哈夫曼编码为 :",c);
code_sum=0;
// 在编码链表中找寻与 c 匹配的编码串
while(*c!='/0') // 字符串未读完
{
hp=hlist->next; //hp 指向编码链表的第一个字符编码组
while(hp->ch!=*c&&hp->next!=NULL) // 尚未找到匹配字符且后面还有字符
hp=hp->next;
// 退出循环的原因可能是找到了匹配字符,也可能是链表读完,需要进一步判断
if(hp->ch==*c) // 找到匹配字符
{
i=0;
while(hp->code[i]!='/0')
printf("%c",hp->code[i++]);
}
code_sum+=i;
c++;
}
printf("/n/n");
}
void analyze() //
编码性能分析
{
int n=0;
printf("/t/t/t 性能分析中 .../n/n");
while(pow(2,n)<char_num) // 计算等长编码情况下需要的编码位数
n++;
printf(" 等长码需要 %d 位 , 编码总长 %d 位 , 本次哈夫曼编码总长 %d , 压缩比 %g/n",n,n*char_amount,code_sum,(float)code_sum/(n*char_amount));
{
int n=0;
printf("/t/t/t 性能分析中 .../n/n");
while(pow(2,n)<char_num) // 计算等长编码情况下需要的编码位数
n++;
printf(" 等长码需要 %d 位 , 编码总长 %d 位 , 本次哈夫曼编码总长 %d , 压缩比 %g/n",n,n*char_amount,code_sum,(float)code_sum/(n*char_amount));
}
main()
{
int choice;
// 初始化,操作包括建立空链表和键盘输入字符串
initial();
{
int choice;
// 初始化,操作包括建立空链表和键盘输入字符串
initial();
//
将接收的字符串依次读入链表中,并统计出现的次数
pull_in_list();
pull_in_list();
//
建立最优二叉树
root=create();
root=create();
//
交互式显示哈夫曼树
if(root!=NULL)
{
printf("/n 哈夫曼树构造完成,是否查看哈夫曼树,输入 1 查看,其它输入跳过 ");
scanf("%d",&choice);
getchar();
if(root!=NULL)
{
printf("/n 哈夫曼树构造完成,是否查看哈夫曼树,输入 1 查看,其它输入跳过 ");
scanf("%d",&choice);
getchar();
if(choice==1)
describe_tree();
}
else
{
printf(" 哈夫曼树未建立,查看字符串中是否只含一种字符,或者重试 /n");
exit();
}
describe_tree();
}
else
{
printf(" 哈夫曼树未建立,查看字符串中是否只含一种字符,或者重试 /n");
exit();
}
//
要挟据建立的最优二叉树进行编码
encoding();
encoding();
//
将原始字符串的哈夫曼编码串输出
codeoutput();
codeoutput();
//
编码性能分析
analyze();
analyze();
printf("/n/n/t/t/tAll Copyright Are Presevered By cobby/n/n
输入任何键退出
/n");
scanf("%d",&choice);
}
scanf("%d",&choice);
}
六、排序
/* 冒泡排序 */
/* 冒泡排序 */
#include<stdlib.h>
#include<stdio.h>
#include<stdio.h>
main()
{
int i,j,temp,a[30000];
long TIME=0;
rand();
{
int i,j,temp,a[30000];
long TIME=0;
rand();
for(i=0;i<30000;i++)
{
a[i]=rand();
printf("%d/t",a[i]);
}
{
a[i]=rand();
printf("%d/t",a[i]);
}
for(i=29999;i>=0;i--)
for(j=0;j<=i;j++)
if(a[j+1]<a[j])
{
TIME++;
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
for(j=0;j<=i;j++)
if(a[j+1]<a[j])
{
TIME++;
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
for(i=0;i<=29999;i++)
printf("%d/t",a[i]);
printf("/n%d/n",TIME);
}
printf("%d/t",a[i]);
printf("/n%d/n",TIME);
}
/* 直接选择排序法 */
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
//#include<time.h>
#include<stdio.h>
#include<math.h>
//#include<time.h>
main()
{
int i,j,value,pos,temp,a[30000];
long TIME=0;
rand();
for(i=0;i<30000;i++) /* make up the rand numbers*/
{
a[i]=rand();
printf("%d/t",a[i]);
}
{
int i,j,value,pos,temp,a[30000];
long TIME=0;
rand();
for(i=0;i<30000;i++) /* make up the rand numbers*/
{
a[i]=rand();
printf("%d/t",a[i]);
}
for(i=0;i<30000;i++) /* sort */
{
value=a[i];
pos=i;
for(j=i+1;j<30000;j++)
{
TIME++;
if(value>a[j])
{
value=a[j];
pos=j;
}
}
temp=a[i];
a[i]=a[pos];
a[pos]=temp;
}
for(i=0;i<30000;i++)
printf("%d/t",a[i]);
printf("/n/n%ld/n",TIME);
}
{
value=a[i];
pos=i;
for(j=i+1;j<30000;j++)
{
TIME++;
if(value>a[j])
{
value=a[j];
pos=j;
}
}
temp=a[i];
a[i]=a[pos];
a[pos]=temp;
}
for(i=0;i<30000;i++)
printf("%d/t",a[i]);
printf("/n/n%ld/n",TIME);
}