目录
顺序表逆置
编写程序实现:
1、在原来的顺序表中将顺序表实现逆置。
2、要求顺序表的内容由用户输入,并分别显示出逆置前和逆置后的顺序表。
定义顺序表的结构体,并对顺序表进行初始化,用malloc 函数申请一片连续的存储空间,增加动态数组的长度,实行动态分配。当n为奇数,将第一个元素与最后一个元素进行交换,第二个与倒数第二个进行交换,以此类推,最中间的元素无需交换;n为偶数,也是将第一个元素与最后一个元素进行交换,第二个与倒数第二个进行交换,以此类推,但最中间两个元素要进行交换。
#include<stdio.h>
#include<stdlib.h>
#define InitSize 100
typedef struct{
int *data;
int Maxsize;
int length;
}SeqList;
void InitList(SeqList &L){
L.data=(int*)malloc(InitSize*sizeof(int));
L.length=0;
L.Maxsize=InitSize;
}
void IncreateSize(SeqList &L,int len){
int *p=L.data;
L.data =(int*)malloc((L.Maxsize+len)*sizeof(int));
for(int i=0;i<L.length;i++){
L.data[i]=p[i];
}
L.Maxsize=L.Maxsize+len;
free(p);
}
void CreatList(SeqList &L, int length){
printf("输入元素值:\n");
for (int i=0;i<length;i++) {
scanf("%d", L.data + i);
L.length = length;
}
}
void PrintList(SeqList &L){
int i=0;
for(;i<L.length;i++){
printf("%d ",L.data[i]);
}
}
void TransList(SeqList &L){
int i,temp;
for(i=0;i<L.length/2;i++){
temp=L.data[i];
L.data[i]=L.data[L.length-1-i];
L.data[L.length-1-i]=temp;
}
}
int main(){
int length;
SeqList L;
InitList(L);
printf("输入多少个元素?\n");
scanf("%d",&length);
IncreateSize(L,length);
CreatList(L,length);
printf("逆置后的结果为:\n");
TransList(L);
PrintList(L);
}
单链表逆置
编写程序实现:
1、在原有的单链表中,将单链表实现逆置。(即不增加新的结点)
2、程序要求单链表的内容由用户输入,并分别显示出逆置前和逆置后的单链表。
定义单链表,申请新的空间head指针指向链表首地址,建立链表,并接收链表首地址,将首地址传递给链表输出函数,输出链表。单链表逆置将最后一个提到最前面,倒数第二个放到第二个,以此类推,直到第一个到最后一个。
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *next;
};
node *Creat(){
node *head=(node*)malloc(sizeof(node));
node *p=head;
int N;
printf("输入多少个元素?\n");
scanf("%d",&N);
printf("输入元素值:\n");
if(N<=0) return NULL;
for(int i=0;i<N;i++){
node *q=(node*)malloc(sizeof(node));
scanf("%d",&(q->data));
q->next=NULL;
p->next=q;
p=p->next;
}
return head;
}
node *Reverse(node *head){
node *p=NULL;
node *next=NULL;
p=head->next;
next=head->next->next;
while(next!=NULL){
p->next=next->next;
next->next=head->next;
head->next=next;
next=p->next;
}
return head;
}
void Output(node *head){
node *p=(node*)malloc(sizeof(node));
p=head;
printf("逆置后的结果为:\n");
while((p=p->next)){
printf("%d ",p->data);
}
free(p);
printf("\n");
}
void Free(node *head)
{
if (head->next==NULL) return;
node *p=head;
while((p=p->next)){
head->next=p->next;
free(p);
p=head;
}
free(head);
}
int main(void){
node *head=Creat();
Reverse(head);
Output(head);
Free(head);
}
火车的调度
编写程序实现:
利用栈解决火车调度问题,将本来杂乱无章的车厢排成 软席(S)在前,硬席(H)在后。车厢序列通过键盘输入,如HSHSHSSSH,输出SSSSSHHHH。
挨个读取字符串,若遇到硬座,将其入栈,若是软座,先入栈后立刻出栈,最后,读取完毕时所有硬座都还在栈内,依次出栈直到栈为空。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MaxSize 100
struct Stack{
char stack[MaxSize];
size_t size;
};
void init(Stack *p){
p->size=0;
}
void push(Stack *p,char ch){
p->stack[p->size++]=ch;
}
bool pop(Stack *p){
if(p->size == 0) return false;
else{
--p->size;
return true;
}
}
bool top(Stack *p,char *ch){
if(p->size == 0) return false;
else{
*ch=p->stack[p->size-1];
return true;
}
}
bool empty(Stack *p){
return p->size == 0;
}
void diaodu(){
Stack s;
char ch,input[MaxSize];
init(&s);
fgets(input,MaxSize,stdin);
input[strlen(input)-1]=0;
printf("????????????");
for(size_t i=0;i<strlen(input);++i){
push(&s,input[i]);
if(top(&s,&ch) && ch=='S'){
pop(&s);
printf("%c",ch);
}
}
while(!empty(&s)){
top(&s,&ch);
pop(&s);
printf("%c",ch);
}
}
int main(){
printf("软席车厢用“S”表示、硬席车厢用“H”表示\n");
printf("请输入车厢序列:");
diaodu();
}
进制转化
编写程序实现:
进制之间的转换:如 将10进制转换为d进制,10进制数n和要转换的进制d通过键盘输入。
由N=(N div d)×d+N mod d得余数,将其从低位到高位获得的数即为转换所求的数,这个原理和栈的先进后出相同,若将计算
过程中得到的数的各位顺序进栈,则按出栈序列输出的就时对应的进制转换后所得的数。
#include<stdlib.h>
#include<stdio.h>
#include<stddef.h>
#define MAXSIZE 100
typedef struct
{ char data[MAXSIZE];
int top;
}sqstack,*psqstack;
psqstack Initstack(){
psqstack s;
s=(psqstack)malloc(sizeof(sqstack));
if(s) s->top=-1;
return s;
}
int Emptystack(psqstack s){
if(s->top==-1) return 1;
else return 0;
}
int Push(psqstack s,char x){
if(s->top==MAXSIZE-1) return 0;
else{
s->top=s->top+1;
s->data[s->top]=x;
return 1;
}
}
int Pop(psqstack s,char *x){
if(Emptystack(s)) return 0;
else{
*x=s->data[s->top];
s->top=s->top-1;
return 1;
}
}
int GetTopstack(psqstack s,char *x){
if(Emptystack(s)) return 0;
else *x=s->data[s->top];
return 1;
}
void Destroystack(psqstack *s){
if(*s)
free(*s);
*s=NULL;
return;
}
void Conversion(int num,int r){
psqstack s;
char x;
if(!r){
printf("基数不能为0");
return;
}
s=Initstack();
if(!s){
printf("初始化栈空间失败");
return;
}
while(num){
if(num%r>9)
Push(s,num%r+'A'-10);
else
Push(s,num%r+'0');
num=num/r;
}
while(!Emptystack(s)){
Pop(s,&x);
printf("%c",x);
}
}
int main(){
int r, num;
printf("请输入要转换的数据");
scanf("%d",&num);
printf("请输入要转换成几进制:");
scanf("%d",&r);
Conversion(num,r);
}
二叉树
编写程序实现:
1、采用递归先序算法建立二叉树,要求通过键盘输入二叉树的先序遍历顺序从而建立一棵二叉树。
2、利用栈实现一棵二叉树的非递归遍历。
3、要求显示遍历次序。
用递归先序算法建立二叉树,输入需要将二叉树补成满二叉树,用空格表示空结点,当遇到“ ”时,令该结点为NULL,结束此分支。递归后序遍历输出先判断非空二叉树后递归遍历左子树,再递归遍历右子树,最后访问根结点,递归先序遍历、递归中序遍历同理。非递归先序遍历,先设置一个栈,判断二叉树是否为空,若为空退出,否则第一次访问的根结点入栈并输出,若有左孩子,将其入栈并输出,若无,取出栈顶结点,若有右子树,重复上述步骤,若无,继续取出栈顶结点,直到结点空、栈空。非递归中序遍历,先将根结点入栈,若有左子树,取出栈顶结点并输出,若有右子树将当前结点入栈,,否则继续取出栈顶结点并输出。
#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW (-2)
typedef char TreeData;
typedef struct node{
TreeData data;
struct node *lchild,*rchild;
}BinTreeNode,*BiTree;
void CreateBiTree(BiTree &T){
TreeData ch=getchar();
if(ch==' ') T=NULL;
else{
if (!(T=(BinTreeNode*)malloc(sizeof(node))))
exit(OVERFLOW);
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
//递归先序
void DLR(BinTreeNode *BiTree){
if(BiTree != NULL){
printf("%c",BiTree->data);
DLR(BiTree->lchild);
DLR(BiTree->rchild);
}
}
//递归中序
void LDR(BinTreeNode *BiTree){
if(BiTree != NULL){
DLR(BiTree->lchild);
printf("%c",BiTree->data);
DLR(BiTree->rchild);
}
}
//递归后序
void LRD(BinTreeNode *BiTree){
if(BiTree != NULL){
DLR(BiTree->lchild);
DLR(BiTree->rchild);
printf("%c",BiTree->data);
}
}
//非递归先序
void PreOrderTraverse(BinTreeNode *BiTree){
BinTreeNode *T=BiTree,*s[100];
int top=0;
while(T||top>0){
if(T){
printf("%c",T->data);
s[top++]=T;
T=T->lchild;
}else{
T=s[--top];
T=T->rchild;
}
}
}
//非递归中序
void InOrderTraverse(BinTreeNode *BiTree){
BinTreeNode *T=BiTree,*s[100];
int top=0;
while(T||top>0){
if(T){
s[top++]=T;
T=T->lchild;
}else{
T=s[--top];
printf("%c",T->data);
T=T->rchild;
}
}
}
int main (){
BiTree T;
printf("请按先序顺序输入二叉树,用空格表示空结点:\n");
CreateBiTree(T);
printf("先序输出:");
DLR(T);
printf("\n中序输出:");
LDR(T);
printf("\n后序输出:");
LRD(T);
printf("\n非递归先序输出:");
PreOrderTraverse(T);
printf("\n非递归中序输出:");
InOrderTraverse(T);
}
图的深度遍历
编写程序实现:
1、实现图的创建。
2、要求显示深度优先遍历次序。
从顶点出发:访问顶点;依次从该顶点的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和该顶点有路径相通的顶点都被访问;若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。
#include <stdio.h>
#define MAX_VERTEX_NUM 20
typedef char VertexType;
typedef struct{//图的定义
VertexType vexs[MAX_VERTEX_NUM ];//顶点表,用一维向量即可, VertexType: char/int
VertexType arcs[MAX_VERTEX_NUM ][MAX_VERTEX_NUM ]; //邻接矩阵
int vexnum,arcnum; //顶点总数,弧(边)总数
}Mgraph;
int LocateVex(Mgraph G,VertexType u){
int i;
for(i=0;i<G.vexnum;++i){
if(u==G.vexs[i]){
return i;
}
}
return -1;
}
void CreateUDN(Mgraph &G){//无向网的构造,用邻接矩阵表示
int i, k, j;
char v1, v2;
printf("输入顶点个数和边数:\n");
printf("顶点数:");
scanf("%d",&G.vexnum);
printf("边数:");
scanf("%d",&G.arcnum);//输入总顶点数,总弧数和信息
printf("输入顶点元素:");
for(i=0;i<G.vexnum;++i){
getchar();//防止读入回车键
scanf("%c",&G.vexs[i]);//输入顶点值,存入一维向量中
}
for(i=0; i<G.vexnum; ++i) {//对邻接矩阵n*n个单元初始化
for(j=0;j<G.vexnum;++j){
G.arcs[i][j]= 0;
}
}
int w;//权值
printf("请输入边的信息:\n");
for(k=0;k<G.arcnum;++k){//给邻接矩阵有关单元赋初值(循环次数=弧数
getchar();
printf("输入弧的两顶点以及对应权值:");
scanf("%c,%c,%d",&v1,&v2,&w); //输入弧的两顶点以及对应权值, 或者scanf(&v1, &v2)
i=LocateVex(G,v1);
j=LocateVex(G,v2); //找到两顶点在矩阵中的位置(n次)
G.arcs[i][j]=w;
G.arcs[j][i] = G.arcs[i][j]; //无向网是对称矩阵
}
}
int visited[MAX_VERTEX_NUM];
void DFS(Mgraph G,int v){
int w;//访问第v个顶点
printf("%c",G.vexs[v]);
visited[v] = 1;
for(w = 0; w< G.vexnum; w++){//依次检查邻接矩阵v所在的行
if((G.arcs[v][w]!=0)&& (!visited[w])){
DFS(G,w);
}
}
}
void DFSTraverse(Mgraph G){//对图 G作深度优先遍历。
int v;
for (v=0; v<G.vexnum; ++v) visited[v] = 0; //访问标志数组初始化
for (v=0; v<G.vexnum; ++v) {
if (!visited[v]) {
DFS(G, v); //对尚未访问的顶点调用DFS
}
}
}
int main() {
Mgraph G;
CreateUDN(G);
printf("深度优先遍历:");
DFSTraverse(G);
return 0;
}
查找的实现
编写程序实现:
1、建立顺序表。
2、分别实现顺序查找、二分查找。
顺序查找从第一个元素开始逐个与需要查找的元素进行比较,当比较到元素值相同时返回此时的下标。二分查找,设有一个从小到大的序列,取中间的元素进行比较,若等于需要查找的元素则返回中间元素的下标,若需要查找的元素大于中间元素则再从右边查找,若需要查找的元素小于中间元素则再从左边查找,这样每次减少一半的查找范围。
/*
**1、建立顺序表。
**2、分别实现顺序查找、二分查找。
*/
#include<stdio.h>
#define MAXSIZE 100
typedef int KeyType;
typedef struct {
KeyType key;
}ElemType;
typedef struct{
ElemType *elem;
int length;
}SeqList;
int CreatList(SeqList &ST){
ST.elem=new ElemType[MAXSIZE+1];
if(!ST.elem) return -1;
printf("请输入顺序表的长度,表长不大于%d:",MAXSIZE);
scanf("%d",&ST.length);
printf("输入元素值:");
for (int i=1;i<=ST.length;i++) { //i=0;i<ST.length错误
scanf("%d",&ST.elem[i].key);
}
}
int Search_Seq(SeqList ST,KeyType key){
int i;
ST.elem[0].key=key;
for(i=ST.length;ST.elem[i].key!=key;--i);
return i;
}
int Search_Bin (SeqList ST,KeyType key) {
int low=1,high=ST.length;
int mid;
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 -1;
}
int main(){
int n;
int index;
SeqList ST;
CreatList(ST);
printf("输入待查询的值:");
scanf("%d",&n);
printf("通过顺序查找:\n");
index=Search_Seq(ST,n);
printf("此数据在表中的位置为:%d\n",index);
printf("通过二分查找:\n");
index=Search_Bin(ST,n);
printf("此数据在表中的位置为:%d\n",index);
return 0;
}
内部排序的实现
编写程序实现:
1、建立待排序表。
2、分别实现直接插入排序、希尔排序。(希尔排序要求必做)
3、要求显示输入待排序的序列和输出排序后的序列。
直接插入排序每次将一个待排序元素与已排序的元素逐一进行比较,直到找到合适的位置。希尔排序首先选择一个步长length/2,按照步长step进行分组即步长是多少就分成多少组,然后分别对每一组进行直接插入排序,然后改变步长step/2,然后再按照步长分组后分别对每一组进行直接插入排序,重复此步骤直到步长为0结束。
/*
**1、建立待排序表。
**2、分别实现直接插入排序、希尔排序。(希尔排序要求必做)
**3、要求显示输入待排序的序列和输出排序后的序列。
*/
#include<stdio.h>
#define MAXSIZE 100
typedef struct{
int data[MAXSIZE];
int length;
}SeqList;
void CreateList(SeqList &L, int n){
L.length = n+1;
printf("请输入元素:\n");
for(int i=1; i<=n; i++){
scanf("%d",&L.data[i]);
}
}
void PrintList(SeqList L){
for(int i=1; i<L.length; i++){
printf("%d ",L.data[i]);
}
}
void InsertSort(SeqList &L){
int i,j;
for(i=2; i<L.length; i++){
if(L.data[i] < L.data[i-1]){
L.data[0] = L.data[i];
for(j=i-1; L.data[0]<L.data[j]; j--){
L.data[j+1] = L.data[j];
}
L.data[j+1] = L.data[0];
}
}
}
void ShellSort(SeqList &L){
int d,i,j;
int n = L.length-1;
for(d=n/2; d>=1; d=d/2){
for(i=d+1; i<=n; i++){
if(L.data[i] < L.data[i-d]){
L.data[0] = L.data[i];
for(j=i-d; j>0&&L.data[0]<L.data[j]; j-=d){
L.data[j+d] = L.data[j];
}
L.data[j+d] = L.data[0];
}
}
}
}
int main(){
SeqList L;
int n;
printf("请输入线性表的长度:\n");
scanf("%d",&n);
CreateList(L, n);
printf("待排序的序列为:\n");
PrintList(L);
printf("\n直接插入排序:\n");
InsertSort(L);
PrintList(L);
printf("\n希尔排序:\n");
ShellSort(L);
PrintList(L);
return 0;
}