数据结构实验

顺序表的基本操作

编写程序实现顺序表的各种基本运算。对给定字符数组a[]={‘1’,‘2’,‘3’,‘1’,‘1’,‘0’,‘4’,‘2’,‘3’,‘1’,‘0’,‘4’,‘2’},创建顺序表L,删除从’2’到’3’的元素。要求时间复杂度为O(n),空间复杂度为O(1)。

#include<stdio.h>
#include<malloc.h>
#include<iostream>
typedef int ElemType;
//顺序表的类型定义 

using namespace std;
struct SqList{
	ElemType arr0[13];
	int length;
	int listsize;
};

//初始化线性表 时间复杂度为O(1) 
void InitList(SqList *&L)
{
	L = (SqList *)malloc(sizeof(SqList));
	L->length = 0;
}

//建立顺序表 
void CreateList(SqList *&L, ElemType a[], int  n)
{
	L = (SqList *)malloc(sizeof(SqList));
	for (int i = 0; i < n; i++)
	{
		L->arr0[i] = a[i];
	}
	L->length = n;
}

//判断线性表是否为空 时间复杂度为O(1) 
bool ListEmpty(SqList *L)
{
	return (L->length == 0);
}

//输出线性表 时间复杂度为O(L->length) 
void DisplayList(SqList *L)
{
	if (ListEmpty(L))
		return;
	for (int i = 0; i < L->length; i++)
		printf("%2d", L->arr0[i]);
	printf("\n");
}

//销毁线性表 时间复杂度为O(1) 
void DestroyList(SqList *&L)
{
	free(L);
}

void node1(SqList *&L,ElemType x,ElemType y)
{

	int k=0,i=0;
	while(i<L->length)
	{
		if(L->arr0[i]>=2&&L->arr0[i]<=3)
		{
			k++;
		}
		else
		{
			L->arr0[i-k]=L->arr0[i];	
		}
		i++;
	}
	L->length-=k;
}

int main()
{
	ElemType x;
	ElemType y;
	ElemType a[]={1,2,3,1,1,0,4,2,3,1,0,4,2};
	SqList *L;

	InitList(L);//初始化线性表
	CreateList(L,a,13);
	printf("L:");
	DisplayList(L);

	x=2;
	y=3;
	node1(L,x,y);
	printf("L:");
	DisplayList(L);
	DestroyList(L);
	return 0;
}

在这里插入图片描述

心得
1.ElemType根据变量类型改变,使程序的复用性更广:
2. InitList(L);//初始化线性表,L = (SqList *)malloc(sizeof(SqList))
3.输出线性表时,需要先判断线性表是否为空。使用布尔函数bool ListEmpty,直接return (L->length == 0);
4.顺序表最好用完销毁, 使用函数void DestroyList(SqList *&L),free(L);
5.时间复杂度为O(n),空间复杂度为O(1)的删除操作有重建法和插入法,这题我们选择的是插入法。

链表基本运算的实现和应用

1、

  1. 假设有一个带头结点的单链表L,每个结点值由单个数字、小写字母和大写字母构成。设计一个算法将其拆分成3个带头结点的单链表L1、L2和L3,L1包含L中的所有数字结点,L2包含L中的所有小写字母结点,L3包含L中的所有大写字母结点。
#include<iostream>
#include<malloc.h>
using namespace std;
typedef char ElemType;
//单链表结点类型声明
typedef struct Node {
    ElemType data;
    struct Node * next;
} LNode, LinkNode;

void DispList(LinkNode * L)
{
    LinkNode * p=L->next;  //p指向首结点
    while(p!=NULL)
    {
        cout<<p->data<<" ";
        p=p->next;    //p移向下一个结点
    }
    cout<<endl;
}
void DestroyList(LinkNode * &L)
{
    LinkNode * pre=L,*p=L->next; //pre指向结点p的前驱结点
    while(p!=NULL)           //扫描单链表L
    {
        free(pre);    //释放pre结点
        pre=p;      //pre、p同步后移一个结点
        p=pre->next;
    }
    free(pre);    //循环结束时p为NULL,pre指向尾结点,释放它
}
//尾插法建立单链表:顺序与数组元素相同 
void CreateListR(LinkNode * &L,char a[],int n)
{
    LinkNode *s,*r;
    L=(LinkNode*)malloc(sizeof(LinkNode));//创建头结点
    r=L;           //r始终指向尾结点,初始时指向头结点
    for(int i=0;i<n;i++)   //循环建立数据结点
    {
        s=(LinkNode*)malloc(sizeof(LinkNode));
        s->data=a[i];       //将结点s插入到结点r之后
        r->next=s;
        r=s;
    }
    r->next=NULL;         //尾结点的next域置为NULL
}

//单链表拆成:纯数字,小写字母,大写字母
void depositeLink(LinkNode *L, LinkNode *L1, LinkNode *L2, LinkNode *L3)
{
    LinkNode * p = L->next;
    //三个表的创建
    (L1) = (LinkNode*)malloc(sizeof(LNode));
    (L2) = (LinkNode*)malloc(sizeof(LNode));
    (L3) = (LinkNode*)malloc(sizeof(LNode));
    //初始化
    LinkNode *p1 = L1;
    p1->next = NULL;
    LinkNode *p2 = L2;
    p2->next = NULL;
    LinkNode *p3 = L3;
    p3->next = NULL;
    //他们的尾节点需要记住
    LinkNode *Tail1 = L1;
    LinkNode *Tail2 = L2;
    LinkNode *Tail3 = L3;
    //遍历单链表
    while (p)
	{
        LinkNode *temp = p; //复制p,将p重新赋值(指向同一地址)
        p = p->next;
		if(temp->data >= 'a' && temp->data <= 'z')
        {
        	//有尾指针,新插进来的前驱后继
            temp->next = Tail2->next;
            Tail2->next = temp;
            //尾指针成为新插进来
            Tail2 = temp;
        }
        else if(temp->data >= 'A' && temp->data <= 'Z')
		{
            temp->next = Tail3->next;
            Tail3->next = temp;
            Tail3 = temp;
        }
        else
		{
            temp->next = Tail1->next;
            Tail1->next = temp;
            Tail1 = temp;
        }
    } 
    cout<<"变化后"<<endl;
    cout<<"L1:";DispList(L1); 
    cout<<"L2:";DispList(L2);
    cout<<"L3:";DispList(L3);
    cout<<"销毁线性表"<<endl;
    DestroyList(L1);
    DestroyList(L2);
    DestroyList(L3);
}

int main()
{
    LinkNode *L,*L1,*L2,*L3;
 //   L=(LinkNode*)malloc(sizeof(LinkNode));
    char a[]={'1','2','3','a','b','4','A','B','5'}; 
    CreateListR(L,a,9);
    cout<<"变化前"<<endl;
    cout<<"L:";DispList(L); 
    depositeLink(L,L1,L2,L3);
    cout<<"销毁线性表"<<endl;
    DestroyList(L);
    return 0;
}

在这里插入图片描述

2、

  1. 试用线性表的链表存储结构来实现约瑟夫(Josephu)问题。约瑟夫问题如下:设有n个人围坐圆桌周围。从某个位置上的人开始从1报数,数到m的人便出列,下一个人(第m+1个)又从1报数开始,数到m的人便是第2个出列的人,依次类推,直到最后一个人出列为止,这样就可以得到一个人员排列的新次序。例如,n=8,m=4,从第1个人数起,得到的新次序为48521376。
#include<stdio.h>
#include<stdlib.h>
 
typedef struct node
{
	int data;
	struct node *next;
}node;
 
node *create(int n)
{
	node *p=NULL,*head;
	head =(node *)malloc(sizeof(node ));
	p=head;
	node *s;
	int i=1;
 
	if(0 != n)
	{
		while(i<=n)
		{
			s=(node *)malloc(sizeof(node));
			s->data =i++;
			p->next=s;
			p=s;
		}
		s->next =head->next;
	}
	free(head);
	return s->next;
}
 
int main()
{
	int n =8;
	int m=4;
	int i;
	node *p=create(n);
	node *temp;
 
	m %=n;
 
	while(p!=p->next)
	{
		for(i=1;i<m-1;i++)
		{
			p=p->next;
		}
		printf("%d ",p->next->data);
		
		temp=p->next;
		p->next=temp->next;
		free(temp);
		 
		p=p->next;
	}
	printf("%d\n",p->data);
	return 0;
}

在这里插入图片描述

栈和队列的应用

可以输入一个任意大小的迷宫数据,用非递归的方法(栈或队列)求出一条走出迷宫的路径,并将路径输出;

#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
#define M 8
#define N 8
int mg[M+2][N+2]=  //迷宫矩阵 
{
	{1,1,1,1,1,1,1,1,1,1},
	{1,0,0,1,0,0,0,1,0,1},
	{1,0,0,1,0,0,0,1,0,1},
	{1,0,0,0,0,1,1,0,0,1},
	{1,0,1,1,1,0,0,0,0,1},
	{1,0,0,0,1,0,0,0,0,1},
	{1,0,1,0,0,0,1,0,0,1},
	{1,0,1,1,1,0,1,1,0,1},
	{1,1,0,0,0,0,0,0,0,1},
	{1,1,1,1,1,1,1,1,1,1}
};
typedef struct
{
	int i;    //当前方块的行号 
	int j;    //当前方块的列号 
	int di;   //下一相邻可走方位号 
} Box;        //方块类型 
typedef Box ElemType;
typedef struct
{
	Box data[MaxSize];
    int top;  //栈顶指针 
} StType;

void InitStack(StType *&s)  //初始化栈 
{	s=(StType *)malloc(sizeof(StType));   //分配空间 
	s->top=-1;  //
}
void DestroyStack(StType *&s)  //释放空间 
{
	free(s);
}
bool StackEmpty(StType *s)  //判断栈为空 
{
	return(s->top==-1);
}
bool Push(StType *&s,ElemType e)  //将Box入栈 
{
	if (s->top==MaxSize-1)
		return false;
	s->top++;
	s->data[s->top]=e;
	return true;
}
bool Pop(StType *&s,ElemType &e)  //将Box出栈 
{
	if (s->top==-1)
		return false;
	e=s->data[s->top];
	s->top--;
	return true;
}
bool GetTop(StType *s,ElemType &e)  //获取栈顶元素 
{
	if (s->top==-1)    //栈首地址 
		return false;
	e=s->data[s->top];
	return true;
}

//迷宫函数
//求解路径为 (xi,yi)到 (xe,ye)
bool mgpath(int xi,int yi,int xe,int ye)  
{
	Box path[MaxSize], e;  //结构体,输出路径 
	int i,j,di,i1,j1,k;
	bool find;  //定义找到的指标:布尔函数 
	StType *st;  //定义栈 
	InitStack(st);  //初始化栈 
	e.i=xi; e.j=yi;	e.di=-1;  //设置入口e 
	Push(st,e);  //方块e进栈 
	mg[xi][yi]=-1;   //设置入口,避免重复走到 
	while (!StackEmpty(st))  //栈不空时循环 
	{
		GetTop(st,e);  //取栈顶元素 
		i=e.i; j=e.j; di=e.di;  
		if (i==xe && j==ye)   //找到出口 
		{
			printf("一条迷宫路径如下:\n");
			k=0;
			while (!StackEmpty(st))
			{
				Pop(st,e);
				path[k++]=e;  //将e填入path路径中 
			}
			while (k>=1)
			{
				k--;
				printf("\t(%d,%d)",path[k].i,path[k].j);
				if ((k+2)%5==0)
					printf("\n");   //每输出五个换一行 
			}
			printf("\n");
			DestroyStack(st);  //销毁栈 
			return true;
		}
		find=false;
		while (di<4 && !find)  //找方块的下一相邻可走方块 
		{
			di++;
			switch(di)  //顺序探索路径 
			{
			//以上左下右的顺序探索路径
//			case 0:i1=i-1; j1=j;   break;
//			case 1:i1=i;   j1=j+1; break;
//			case 2:i1=i+1; j1=j;   break;
//			case 3:i1=i;   j1=j-1; break;
            //以下右上左的顺序探索路径
			case 0:i1=i+1; j1=j;   break;
			case 1:i1=i;   j1=j-1; break;
			case 2:i1=i-1; j1=j;   break;
			case 3:i1=i;   j1=j+1; break;
			}
			if (mg[i1][j1]==0) find=true;
		}
		if (find)  //入栈操作 
		{

			st->data[st->top].di=di;
			e.i=i1; e.j=j1; e.di=-1;
			Push(st,e);
			mg[i1][j1]=-1;
		}
		else
		{
			Pop(st,e);
			mg[e.i][e.j]=0;  //恢复可走标识 
		}
	}
	DestroyStack(st);  //销毁栈 
	return false;  //没有可走路径 
}

int main()
{
//	mgpath(1,1,M,N);
    if(!mgpath(1,1,M,N))
	    printf("该迷宫问题没有解!"); 
	return 1;
}


心得
跟着老师上课的思路进行代码编写,整体比较丝滑。由于一直入口在最左上角,出口在最右下角。因此我们将书上上左下右依次顺序探索路径,改为通过下右上左的顺序探索路径,从而降低时间复杂度。

二叉树遍历算法及其应用

以二叉链表存储结构的方式创建如下图的二叉树,输入时将下图二叉树变为基于括号表示的字符串。创建二叉树和实现二叉树的三种遍历和层次遍历。最后求出叶子节点个数和二叉树深度。
在这里插入图片描述

#include <stdio.h>
#include <malloc.h>
#include <iostream>
#include <cstdio>

#define MaxSize 100
using namespace std;
typedef char ElemType;
int cnt;

typedef struct BTNode  //结构体二叉树 
{
    ElemType data;
    struct BTNode* rchild;
    struct BTNode* lchild;
}node;
typedef struct  //队列 
{	
	BTNode* data[MaxSize];
	int front,rear;						//队头和队尾指针
} Queue;

void CreateBTree(BTNode * &b,char * str)  //创建二叉树 
{
    BTNode * St[MaxSize],*p;
    int top=-1,k,j=0;
    char ch;
    b=NULL;
    p=NULL;
    ch=str[j];
    while(ch!='\0')
    {
    	switch(ch)
    	{
    		case '(':top++;St[top]=p;k=1;break; //开始处理左孩子节点
			case ')':top--;break;           //栈顶节点的子树处理完毕 
			case ',':k=2;break;   //开始处理右孩子节点
			default:p=(BTNode *)malloc(sizeof(BTNode));
			        p->data=ch;
					p->lchild=p->rchild=NULL;
					if (b==NULL)
					    b=p;
					else
					{
						switch(k)
						{
							case 1:St[top]->lchild=p;break;
							case 2:St[top]->rchild=p;break;
						}
					}	
		}
        j++;
        ch=str[j];
	}
}

void preOrderTraver(BTNode*& b)//先序遍历 
{
    if(b!=NULL)
    {
        cout<<b->data<<" ";
        preOrderTraver(b->lchild);
        preOrderTraver(b->rchild);
    }
}
void InOrderTraver(BTNode*& b)//中序遍历
{
    if(b!=NULL)
    {
        InOrderTraver(b->lchild);
        cout<<b->data<<" ";
        InOrderTraver(b->rchild);
    }
}
void posOrderTraver(BTNode*& b)//后序遍历
{
    if(b!=NULL)
    {
        posOrderTraver(b->lchild);
        posOrderTraver(b->rchild);
        cout<<b->data<<" ";
    }
}

void InitQueue(Queue *&q)
{	q=(Queue *)malloc (sizeof(Queue));
	q->front=q->rear=-1;
}
void DestroyQueue(Queue *&q)			//销毁队列
{
	free(q);
}
bool QueueEmpty(Queue *q)				//判断队列是否为空
{
	return(q->front==q->rear);
}
bool enQueue(Queue *&q,BTNode *e)	//进队
{	if (q->rear==MaxSize-1)				//队满上溢出
		return false;					//返回假
	q->rear++;							//队尾增1
	q->data[q->rear]=e;					//rear位置插入元素e
	return true;						//返回真
}
bool deQueue(Queue *&q,BTNode *e)	//出队
{	if (q->front==q->rear)				//队空下溢出
		return false;
	q->front++;
	e=q->data[q->front];
	return true;
}
int QueueFront(Queue *&q)
{
    return q->front;
}

void BinaryTreeLevelOrder(BTNode* b)//层次遍历(队列) 
{
    Queue *pq;
    //树为空,直接返回
    if (b == NULL)
    {
        return;
    }
    InitQueue(pq);
    //先将根节点入队
    enQueue(pq, b);
    while (QueueEmpty(pq))
    {
        //出队保存队头并访问
//        BTNode* front = QueueFront(pq);
        deQueue(pq,b); 
        printf("%c", pq->data);
        //将出队结点的左子树根入队
        if (b->lchild)
            enQueue(pq, b->lchild);
        //将出队结点的右子树根入队
        if (b->rchild)
            enQueue(pq, b->rchild);
    }
}

int BTHeight(BTNode *b)///二叉树的深度
{
    int ans = 0;
    if(b == NULL) return 0;
    else
        ans += max(ans,max(BTHeight(b->lchild),BTHeight(b->rchild))+1);
    return ans;
}
int BTLeafNode(BTNode *b)   //输出二叉树的叶子节点,并计数 
{
    if(b != NULL)
    {
        if(b->lchild == NULL && b->rchild == NULL)
        {
            printf("%c",b->data);
            cnt++;
        }
        else
        {
            BTLeafNode(b->lchild);
            BTLeafNode(b->rchild);
        }
    }
    return cnt;
}

int main()
{
    BTNode *b;
    ElemType str[]="A(B(D(,G)),C(E,F))";
    CreateBTree(b,str);
    cout<<"先序遍历结果"<<endl;
    preOrderTraver(b);cout<<endl;
    cout<<"中序遍历结果:"<<endl;
    InOrderTraver(b);cout<<endl;
    cout<<"后序遍历结果:"<<endl;
    posOrderTraver(b);cout<<endl;
    cout<<"层次遍历结果:"<<endl;
    BinaryTreeLevelOrder(b);cout<<endl;
    printf("\n输出二叉树的深度:");
    int sum = BTHeight(b);
    cout << sum << endl;
    printf("输出二叉树的叶子结点:");
    int ans = BTLeafNode(b);
    printf("\n输出二叉树的叶子结点的个数:");
    cout << ans << endl;
    return 0;
}

在这里插入图片描述

心得
①case ‘(’
注意case后面的空格
②typedef是在计算机编程语言中用来为复杂的声明定义简单的别名,它与宏定义有些差异。它本身是一种存储类的关键字
③由于创建二叉树时代码错误,因而遍历结果显示只有一个元素。对其进行修改后,得到正确答案。

在这里插入图片描述

图的遍历算法及其应用

请自行构建一个有8个节点、大于等于15条边的无向图,编写程序显示该图,并实现图的深度优先遍历和广度优先遍历算法。(图的存储结构为邻接表)。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<malloc.h>
#define MAXV 8
#define INF 980708
#define N 8
using namespace std;

typedef int InfoType;
//邻接表
 typedef struct ANode
 {
 	int adjvex;
 	struct ANode *nextarc;
 	int weight;
 } ArcNode;//边结点类型

 typedef struct Vnode
 {
 	InfoType info;
 	ArcNode *firstarc;
 } VNode;//邻接表的头结点类型
 typedef struct 
 {
 	VNode adjlist[MAXV];
 	int n,e;
 } AdjGraph;//完整的图邻接表类型

 typedef struct
 {
 	InfoType data[MAXV];
	 int front,rear;	
 }SqQueue; //队列

 //初始化队列
 void InitQueue(SqQueue *&q)
 {
 	q=(SqQueue*)malloc(sizeof(SqQueue));
 	q->front=q->rear=-1;
 } 
 //判断队列是否为空
bool QueueEmpty(SqQueue *q)
 {
 	return(q->front==q->rear);
 } 
 //进队列
 bool enQueue(SqQueue *&q,InfoType e)
 {
 	if(q->rear==MAXV)return false;
 	q->rear++;
 	q->data[q->rear]=e;
 	return true;
 } 
 //出队列
 bool deQueue(SqQueue *&q,InfoType &e)
 {
 	if(q->front==q->rear)return false;
 	q->front=(q->front+1)%MAXV;
 	e=q->data[q->front];
 	return true;
 } 

 //创建邻接表
 void CreateAdj(AdjGraph *& G,int A[MAXV][MAXV],int n,int e)
 {
 	int i,j;
	ArcNode *p;
 	G=(AdjGraph*)malloc(sizeof(AdjGraph));
 	for(i=0;i<n;i++)
 		G->adjlist[i].firstarc=NULL;
	for(i=0;i<n;i++)
		for(j=n-1;j>=0;j--)
			if(A[i][j]!=0&&A[i][j]!=INF)
			{
				p=(ArcNode*)malloc(sizeof(ArcNode));
				p->adjvex=j;
				p->nextarc=G->adjlist[i].firstarc;
				G->adjlist[i].firstarc=p;
			}
	G->n=n;G->e=e;
 } 

 //输出邻接表 
 void DispAdj(AdjGraph *G)
 {
 	cout<<"邻接表存储:"<<endl;
 	int i;ArcNode *p;
 	for(i=0;i<G->n;i++)
 	{
	 	p=G->adjlist[i].firstarc;
	 	printf("%3d:",i);
	 	printf("%3d[ ]->",i);
	 	while(p!=NULL)
	 	{
	 		printf("%3d[ ]->",p->adjvex);
	 		p=p->nextarc;
	 	}
	 	cout<<"^"<<endl;
	 }
 }

  //DFS深度优先遍历
 int visited[MAXV]={0};
 void DFS(AdjGraph *G,int v)
 {
 	ArcNode *p;
 	visited[v]=1;
 	cout<<v<<" ";
 	p=G->adjlist[v].firstarc;
 	while(p!=NULL)
 	{	
		if(visited[p->adjvex]==0)
			DFS(G,p->adjvex);
		p=p->nextarc; 	
 	}
 }

 //BFS广度优先遍历
 void BFS(AdjGraph *G,int v)
 {
 	int w,i;ArcNode *p;
 	SqQueue *qu;
 	InitQueue(qu);
 	int visited1[MAXV];
 	for(int i=0;i<G->n;i++)
	 	visited1[i]=0;
	cout<<v<<" ";
 	visited1[v]=1;
 	enQueue(qu,v);
 	while(!QueueEmpty(qu))
 	{
	 	deQueue(qu,w);
	 	p=G->adjlist[w].firstarc;
	 	while(p!=NULL)
	 	{
	 		if(visited1[p->adjvex]==0)
	 		{
	 			cout<<p->adjvex<<" ";
				visited1[p->adjvex]=1;
				enQueue(qu,p->adjvex); 
		 	}
		 	p=p->nextarc;
	 	}
	 }
	 cout<<endl;
 }  

 //销毁邻接表 
 void DestroyAdj(AdjGraph *&G)
 {
 	int i;ArcNode *pre,*p;
 	for(i=0;i<G->n;i++)
 	{
	 	pre=G->adjlist[i].firstarc;
	 	if(pre!=NULL)
	 	{
	 		p=pre->nextarc;
	 		while(p!=NULL)
	 		{
		 		free(pre);
		 		pre=p;p=p->nextarc;
		 	}
		 	free(pre);
	 	}
	 }
	 free(G);
 } 

 int main()
 {
 	int n,e,v,v1;
 	AdjGraph *p;
	n=N;
 	e=15;
 	int G[N][N]={{1,0,0,0,1,1,0,1},
	             {0,0,0,0,1,1,0,1},
				 {0,0,1,0,0,1,0,1},
				 {0,0,0,0,1,0,0,0},
				 {1,1,0,1,0,0,1,0},
				 {1,1,1,0,0,0,1,0},
				 {0,0,0,0,1,1,0,1},
				 {1,1,1,0,0,0,1,1}
				};
 	CreateAdj(p,G,n,e);
 	DispAdj(p);
 	cout<<"进行DFS深度优先遍历,请输入初始点:";
 	cin>>v;
 	DFS(p,v);
 	cout<<endl; 
 	cout<<"进行BFS广度优先遍历,请输入初始点:";
 	cin>>v1;
 	BFS(p,v1);
 	cout<<"销毁图"<<endl;
 	DestroyAdj(p);
 }

在这里插入图片描述

心得
创建图:根据邻接矩阵数组A、顶点个数n和边数e来建立图的邻接表G。首先为邻接表分配G的存储空间,并将所有的头结点firstarc指针设置为空。依次创建adjvex为A[i][j]的边结点,采用头插法插入第i个单链表中。
输出图:扫描头结点数组adjlist,先输出头结点顶点信息,然后逐一输出单链表所有结点的顶点编号。
销毁图:扫描头结点数组adjlist指向的所有单链表,逐个释放单链表边结点,最后释放头结点数组。

查找和排序算法设计

1

1、编写程序输出在顺序表{1,2,3,4,5,6,7,8,9,10}中采用折半查找法查找关键字9的过程。

#include <stdio.h>
#define MAXL 100                    //定义表中最多记录个数
typedef int KeyType;
typedef char InfoType[10];
typedef struct
{
    KeyType key;                    //KeyType为关键字的数据类型
    InfoType data;                  //其他数据
} NodeType;
typedef NodeType SeqList[MAXL];             //顺序表类型
int BinSearch(SeqList R,int n,KeyType k)    //二分查找算法
{
    int low=0,high=n-1,mid,count=0;       //存在元素时循环 
    while (low<=high)
    {
        mid=(low+high)/2;          //确定中点位置 
        printf("  第%d次比较:在[%d,%d]中比较元素R[%d]:%d\n",++count,low,high,mid,R[mid].key);
            if (R[mid].key==k)      //查找成功返回序号 mid+1 
            return mid+1;
        if (R[mid].key>k)       //继续在R[low..mid-1]中查找
            high=mid-1;
        else
            low=mid+1;          //继续在R[mid+1..high]中查找
    }
    return 0;               //未找到返回0(查找失败) 
}
int main()
{
    SeqList R;
    KeyType k=9;
    int a[]={0,1,2,3,4,5,6,7,8,9},i,n=10;
    for (i=0;i<n;i++)               //建立顺序表
        R[i].key=a[i];
    printf("关键字序列:");
    for (i=0;i<n;i++)
        printf("%d ",R[i].key);
    printf("\n");
    printf("查找%d的比较过程如下:\n",k);
    if ((i=BinSearch(R,n,k))!=-1)
        printf("元素%d的位置是%d\n",k,i);
    else
        printf("元素%d不在表中\n",k);
}

在这里插入图片描述

2

2、编写快速排序算法,并输出{6,8,7,9,0,1,3,2,4,5}的排序过程。

#include<stdio.h>

void swap(int *x, int *y)  //交换 
{
    int tmp = *x;
    *x = *y;
    *y = tmp;
}

int patition(int *a, int left,int right) //把数组分成两份
{
    int j = left;    //遍历数组
    int i = j - 1;    //指向小于基准元素的位置
    int key = a[right];    //基准元素
    for (; j < right; ++j) //从左到右遍历数组,把小于等于基准元素的放到左边,大于基准元素的放到右边
	{
        if (a[j] <= key)
            swap(&a[j], &a[++i]);
    }
    swap(&a[right], &a[++i]); //把基准元素放到中间
    return i;//返回数组中间位置
}

void quickSort(int *a,int left,int right) //快速排序
{
    if (left>=right)
        return;
    int mid = patition(a,left,right);
    quickSort(a, left, mid - 1);
    quickSort(a, mid + 1, right);
}

int main() 
{
    int a[] = { 6,7,8,9,1,2,3,4,5,0 };
    int n = sizeof(a) / sizeof(int);
    quickSort(a, 0,n-1);
    printf("排好的数组为:");
    for (int l = 0; l < n; l++) 
	{
        printf("%d ", a[l]);
    }
    printf("\n");
    return 0;
}

在这里插入图片描述

实验心得
考完试整理压缩包,结果误删除了而且恢复不了。无奈之下全部重新整理了一遍。不得不说,在复习完全部原理,对数据存储结构更为了解后,代码写起来更为顺畅,十分丝滑。
记得第一次写实验题目写了一整个下午,不停地修改报错,后面代码报错逐步减少,再到最后的综合实验八皇后。总的来说,十分感动也很荣幸,达到今天的代码能力。一路感知进步,遇见更好的自己,这是件十分快乐的事情。

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是Yu欸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值