2021数据结构考研辅导指导

  • 试编写一个算法,判断给定的二叉树是否是二叉排序树。
KeyType predt=-32767;
int JudgeBST(BiTree bt){
     
    int b1,b2;
    if(bt==NULL)
        return 1;
    else{
     
        b1=JudgeBST(bt->lchild);
        if(b1=0||predt>bt->data)
            return 0;
        predt=bt->data;
        b2=JudgeBST(bt->rchild);
        return b2;
    }
}
  • 写出从图的邻接表表示转换成邻接矩阵表示的算法。
void Convert(ALGraph &G,int arcs[M][N]{
     
    //此算法将邻接表方式表示的图G转换为邻接矩阵ares
    for(i=0;i<n;i++){
                 //依次遍历各顶点表结点为头的边链表
        p=(G->v[i].firstarc;     //取出顶点i的第一条边
        while(p!=NULL){
     //遍历边链表
            arcs[i][p->data]=1;
            p=p->nextarc;        //取出下一条出边
        }
    }
}
  • 广度优先搜索遍历算法
bool visited[MAX_VERTEX_NUM];		//访问标记数组
void BFSTraverse(graph G){
     			//对图G进行广度优先遍历
	for(i=0;i<G.vexnum;i++)			
		visited[i]=FALSE;			//访问标记数组初始化
	InitQueue(Q);					//初始化辅助队列Q
	for(i=0;i<G.vexnum;i++)			//从0号顶点开始遍历
		if(!visited[i])				//对每个连通分量调用一次BFS
			BFS(G,i);				//Vi未访问过,从Vi开始BFS
}
void BFS(Graph G,int v){
     			//从顶点v出发,广度优先遍历图G
	visit(v);						//访问初始顶点v
	visited[v]=TRUE;				//对v做已访问标记
	Enqueue(Q,v);					//顶点v入队伍Q
	while(!isEmpty(Q)){
     
		Dequeue(Q,v);				//顶点v出队列
		for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v.w))	//检测v所有的邻接点
			if(!visited[w]){
     		//w为v的尚未访问的邻接顶点
				visit(w);			//访问顶点w
				visited[w]=TRUE;	//对w做已访问过标记
				EnQueue(Q,w);		//顶点w入队伍
			}
	}
}
  • 深度优先遍历算法(递归形式)
bool visited[MAX_VERTEX_NUM];		//访问标记数组
void DFSTraverse(Graph G){
     			//对图G进行深度优先遍历
	for(v=0;v<G.vexnum;++v)
		visited[v]=FALSE;			//初始化已访问标记数组
	for(v=0;v<G.vexnum;++v)			//本代码中是从v=0开始遍历
		if(!visited[v])
			DFS(G,v);
}
void DFS(Graph G,int v){
     			//从顶点v出发,深度优先遍历图G
	visit(v);						//访问顶点v
	visited[v]=TURE;				//设已访问标记
	for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w))
		if(!visited[w]){
     			//w为u的尚未访问的邻接顶点
			DFS(G,w);
		}
}
  • 直接插入排序

此算法在理解方面优于带哨兵的算法

void InsertSort(ElemType A[],int n){
     
	int i,j,temp;
	for(i=1;i<n;i++)							//将各元素插入已排好序的的序列中
		if(A[i]<A[i-1]){
     						//若A[i]关键字小于前驱
			temp=A[i];							//用temp暂存A[i]
			for(j=i-1;j>=0 && A[j]>temp;--j)	//检查所有前面已排好序的元素
				A[j+1]=A[j];					//所有大于temp的元素都向后挪位
			A[j+1]=temp;						//复制到插入位置
		}
}

直接插入排序的带“哨兵”的实现方法

void InsertSort(ElemType A[],int n){
     
	int i,j;
	for(i=2;i<=n;i++)					//依次将A[2]~A[n]插入到前面已排好序序列
		if(A[i]<A[i-1]){
     				//若A[i]关键码小于其前驱,将A[i]插入有序表
			A[0]=A[i];					//复制为哨兵,A[0]不存放元素
			for(j=i-1;A[0]<A[j];--j)	//从后往前查找待插入位置
				A[j+1]=A[j];			//向后挪位
			A[j+1]=A[0];				//复制到插入位置
		}
}
  • 折半插入排序算法
void InsertSort(ElemType A[],int n){
     
	int i,j,low,high,mid;
	for(i=2;i<=n;i++){
     			//依次将A[2]~A[n]插入前面的已排好序序列
		A[0]=A[i];				//将A[i]暂存到A[0]
		low=1;
		high=i-1;			//设置折半查找的范围
		while(low<=high){
     		//折半查找(默认递增有序)
			mid=(low+high)/2;	//取中间点
			if(A[mid]>A[0])
				high=mid-1;		//查找左半子表
			else
				low=mid+1;		//查找右半子表
		}
		for(j=i-1;j>=high+1;--j)
			A[j+1]=A[j];		//统一后移元素,空出插入位置
		A[high+1]=A[0];			//插入操作
	}	
}
  • 希尔排序
void ShellSort(ElemType A[],int n){
     
	int d,i,j;									//A[0]只是暂存单元,不是哨兵,当j<=0时,插入位置已到
	for(d=n/2; d>=1; d=d/2)						//步长变化
		for(i=d+1; i<=n; ++i)
			if(A[i]<=A[i-d])					//需将A[i]插入有序增量子表
				A[0]=A[i];						//暂存在A[0]
				for(j=i-d;j>0&&A[0]<A[j];j-=d)
					A[j+d]=A[j];				//记录后移,查找插入的位置
				A[j+d]=A[0];					//插入
}
  • 冒泡排序算法
void swap(int &a,int &b){
     
	int temp = a;
	a = b;
	b = temp;
}

void BubbleSort(ElemType A[],int n){
     
	for(i=0;i<n-1;i++){
     
		bool flag=false;			//表示本趟冒泡是否发生交换的标志
		for(int j=n-1;j>i;j--)		//一趟冒泡过程
			if(A[]j-1]>A[j]){
     		//若为你序
				swap(A[j-1],A[j]);	//交换
				flag=ture;
			}
		if(flag==falsh)
			return;					//本趟遍历后没有发生交换,说明表已经有序
	}
}
  • 快速排序

考试重点,要牢记!!!

void QuickSort(ElemType A[],int low,int high){
     
	if(low<hjgh){
     		//递归跳出的条件
						//Partition()就是划分操作,将表A[low···hjgh]划分为满足上述条件的两个子表
		int pivotpos=Partition(A,low,high);		//划分
		QuickSort(A,low,pivotpos-1);			//依次对两个子表进行递归排序
		QuickSort(A,pivotpos+1,high);
	}
}

int Partition(ElemType A[],int low,int high){
     		//一趟划分
	ElemType pivot=A[low];			//将当前表中第一个元素设为枢轴,对表进行划分
	while(low<high){
     		//循环跳出条件
		while(low<high&&A[high]>=pivot)
			--high;
		A[low]=A[high];		//将比枢轴小的元素移动到左端
		while(low<high&&A[low]<=pivot)
			++low;
		A[high]=A[low];		//将比枢轴大的元素移动到右端
	}
	A[low]=pivot;			//枢轴元素存放到最终位置
	return low;				//返回存放枢轴的最终位置
}
  • 简单选择排序
//交换
void swap(int &a,int &b){
     
	int temp = a;
	a = b;
	b = temp;
}

//简单选择排序
void SelectSort(ElemType A[],int n){
     
	for(int i=0;i<n-1;i++){
     			//一共进行n-1趟
		int min=1;					//记录最小元素位置
		for(int j=i+1;j<n;j++)		//在A[i···n-1]中选择最小的元素
			if(A[j]<A[min])
				min=j;				//更新最小元素位置
		if(min!=i)
			swap(A[i],A[min]);
	}
}
  • 堆排序

基于“大根堆”的堆排序。即根结点的值大于左右子树任何一个结点的值,根结点的值是最大的。

//建立大根堆
void BuildMaxHeap(ElemType A[],int len){
     
	for(int i=len/2;i>0;i--)			//从后往前调整所有非终端结点
		HeadAdjust(A,i,len);
}

//将以k为根的子树调整为大根堆
void HeadAdjust(ElemType A[],int k,int len){
     
	A[0]=A[k];							//A[0]暂存子树的根节点
	for(int i=2*k;i<=len;i*=2){
     			//沿key较大的子结点向下筛选
		if(i<len&&A[i]<A[i+1])			//"i
			i++;						//取key较大的子结点的下标
		if(A[0]>=A[i])
			break;						//筛选结束
		else{
     
			A[k]=A[i];					//将A[i]调整到双亲结点上
			k=i;						//修改k值,以便继续向下筛选
		}
	}
	A[k]=A[0];							//被筛选结点的值放入最终位置
}

//堆排序的完整逻辑
void HeapSort(ElemType A[],int len){
     
	BuildMaxHeap(A,len);				//初始建堆
	for(int i=len;i>1;i--){
     				//n-1趟的交换和建堆过程
		swap(A[i],A[1]);				//堆顶元素和堆底元素交换
		HeadAdjust(A,1,i-1);			//把剩余的待排序元素整理成堆
	}
}

//swap交换函数
void swap(int &a,int &b){
     
 int temp = a;
 a = b;
 b = temp;
}

你可能感兴趣的:(笔记,算法)