PTA浙大版《数据结构(第2版)》题目集 参考答案(函数题)

本文档提供了浙江大学数据结构课程中的部分习题解答,包括二分查找、有序数组插入、链表操作、哈希表、图的遍历方法等,有助于学习者理解和实践相关算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PTA浙大版《数据结构(第2版)》题目集 参考答案(函数题)

本答案配套详解教程专栏,专栏中对每个题目答案有更详细解析,欢迎订阅专栏。

专栏链接:PTA浙大版《数据结构(第2版)》题目集 详解教程_少侠PSY的博客-CSDN博客

习题1.8 二分查找

Position BinarySearch( List L, ElementType X ){
    int left,mid,right;
    left = 1;
    right = L->Last;
	while( left<=right ){
		mid = (left+right)/2;
		if( X==L->Data[mid] ) return mid;
		if( X>L->Data[mid] ) left = mid+1;
		else right = mid-1;
	}
	if( left>right ) return NotFound;
}

习题1.9 有序数组的插入

bool Insert( List L, ElementType X ){
    bool insert;
    if (L->Last+1 >= MAXSIZE)insert = false;
    else{
        for (int i = 0; i <= L->Last; i++){
            if (X == L->Data[i]){
                insert = false;
                break;
            }
            if (X > L->Data[i]){
                for (int j = L->Last+1; j > i; j--)
                    L->Data[j] = L->Data[j-1];
                L->Data[i] = X;
                L->Last++;
                insert = true;
                break;
            }
            if (i == L->Last && X < L->Data[i]){
                L->Data[L->Last+1] = X;
                L->Last++;
                insert = true;
                break;
            }
        }
    }
        return insert;
}

习题2.4 递增的整数序列链表的揷入

List Insert( List L, ElementType X ){
    List emptyL = (List)malloc(sizeof(struct Node));
    List NewL = L;
    emptyL->Data = X;
    if (NewL->Next == NULL){//原链表为空
        emptyL->Next = NULL;
        NewL->Next = emptyL;
    }else if(NewL->Next->Data >= X){//X比链表第一个值更大,X加在链表最前面
            emptyL->Next = NewL->Next;
            NewL->Next = emptyL;
    }else{
        while (NewL->Next != NULL && NewL->Next->Data < X)
            NewL = NewL->Next;
        if (NewL->Next == NULL){
            emptyL->Next = NULL;
            NewL->Next = emptyL;
        }else{
            emptyL->Next = NewL->Next;
            NewL->Next = emptyL;
        }
    }
    return L;
}

习题2.5 两个有序链表序列的合并

List Merge(List L1, List L2){
    List Merge,tail;
    Merge=(List)malloc(sizeof(struct Node));
    Merge->Next=NULL;
    tail=Merge;
    while(L1->Next&&L2->Next){
        if(L1->Next->Data<L2->Next->Data){
            tail->Next=L1->Next;
            L1->Next=L1->Next->Next;
            tail=tail->Next;
            tail->Next=NULL;
        }else{
            tail->Next=L2->Next;
            L2->Next=L2->Next->Next;
            tail=tail->Next;
            tail->Next=NULL;
        }
    }
    if(L1->Next){
        tail->Next=L1->Next;
        L1->Next=NULL;
    }
    if(L2->Next){
        tail->Next=L2->Next;
        L2->Next=NULL;
    }
    return Merge;
}

习题2.6 递归求简单交错幂级数的部分和

double fn( double x, int n ){
    if(n == 1 )return x ;
    else return x*(1 - fn(x,n-1)) ;
}

习题2.7 弹球距离

double dist( double h, double p ){
    double sum = 0;
    if( h >= TOL )sum = h + h * p + dist(h * p , p) ;
    if( h * p < TOL)sum = h ;
    return sum ;
}

习题3.3 线性表元素的区间删除

List Delete( List L, ElementType minD, ElementType maxD ){
    Position i;
    int len = 0 ;
    for(i = 0 ; i <= L->Last ; i++ ){
        if(L->Data[i]>minD && L->Data[i]<maxD )continue;
        else L->Data[len++] = L->Data[i];
    }
    L->Last = len -1 ;
    return L;
}

习题3.5 求链表的倒数第 m 个元素

ElementType Find( List L, int m ){
    List Head = L;
    int sum = 0;
    while(L->Next) {
        L = L->Next;
        sum++;
    }
    if(m > sum) return ERROR;
    int t;
    L = Head -> Next;
    for(int i = 0; i < (sum - m); i++)L = L->Next;
    t = L->Data;
    return t;
}

习题3.12 另类循环队列

bool IsFull( Queue Q ){
	return (Q->Count == Q->MaxSize);
}

bool AddQ( Queue Q, ElementType X ){
	if ( IsFull(Q) ) {
		printf("Queue Full\n");
		return false;
	}
	else {
		Q->Data[(Q->Front+Q->Count+1)%Q->MaxSize] = X;
        Q->Count++;
		return true;
	}
}

bool IsEmpty( Queue Q ){
	return (Q->Count==0);
}

ElementType DeleteQ( Queue Q ){
	if ( IsEmpty(Q) ) { 
		printf("Queue Empty\n");
		return ERROR;
	}
	else  {
		Q->Front =(Q->Front+1)%Q->MaxSize;
		Q->Count--;
		return  Q->Data[Q->Front];
	}
}

习题3.13 双端队列

bool IsFull( Deque D ){
	return ((D->Front-D->Rear+D->MaxSize)%D->MaxSize == 1);
}
bool IsEmpty( Deque D ){
	return (D->Front == D->Rear);
}

bool Push( ElementType X, Deque D ){
     if (IsFull(D)) return false;
     D->Front = (D->Front-1+D->MaxSize)%D->MaxSize;
     D->Data[D->Front] = X;
     return true;
}

ElementType Pop( Deque D ){
     ElementType X;
     if (IsEmpty(D)) return ERROR;
     X = D->Data[D->Front];
     D->Front = (D->Front+1)%D->MaxSize;
     return X;
}

bool Inject( ElementType X, Deque D ){
     if (IsFull(D)) return false;
     D->Data[D->Rear] = X;
     D->Rear = (D->Rear+1)%D->MaxSize;
     return true;
}

ElementType Eject( Deque D ){
     if (IsEmpty(D)) return ERROR;
     D->Rear = (D->Rear-1+D->MaxSize)%D->MaxSize;
     return D->Data[D->Rear];
}

习题3.14 另类堆栈

bool IsFull( Stack S ){
	return (S->Top == S->MaxSize);
}

bool Push( Stack S, ElementType X ){
	if ( IsFull(S) ) {
		printf("Stack Full\n");
		return false;
	}
	else {
		S->Data[S->Top++] = X;
        return true;
    }
}

bool IsEmpty( Stack S ){
	return (S->Top == 0);
}

ElementType Pop( Stack S ){
	if ( IsEmpty(S) ) {
		printf("Stack Empty\n");
		return ERROR; 
	}
	else 
		return ( S->Data[--(S->Top)] );
}

习题4.3 是否二叉搜索树

#include <stdio.h>

#define MAXN 1001
#define MINH -10001

int H[MAXN], size;

void Create (){
	size = 0;
	H[0] = MINH;
}

void Insert ( int X ){ 
	int i;
	for (i=++size; H[i/2] > X; i/=2)
		H[i] = H[i/2];
	H[i] = X;
}

int main(){
	int n, m, x, i, j;

	scanf("%d %d", &n, &m);
	Create();
	for (i=0; i<n; i++) {
		scanf("%d", &x);
		Insert(x);
	}
	for (i=0; i<m; i++) {
		scanf("%d", &j);
		printf("%d", H[j]);
		while (j>1) {
			j /= 2;
			printf(" %d", H[j]);
		}
		printf("\n");
	}
	return 0;
}

习题5.10 线性探测法的查找函数

Position Find( HashTable H, ElementType Key ){
	Position CurrentPos, NewPos;
	NewPos = CurrentPos = Hash( Key, H->TableSize );
	while( H->Cells[NewPos].Info!=Empty && H->Cells[NewPos].Data!=Key ) {
           NewPos ++;
	       if ( NewPos >= H->TableSize )
				NewPos -= H->TableSize;
	       if (NewPos == CurrentPos) return ERROR;
	}
	return NewPos;
}

习题5.11 分离链接法的删除操作函数

bool Delete( HashTable H, ElementType Key ){
     Position P, t;
     Index Pos;
     
     Pos = Hash( Key, H->TableSize );
     P = H->Heads+Pos;
     while( P->Next && strcmp(P->Next->Data, Key) )
        P = P->Next;
     if (!P->Next) return false;
     else {
          t = P->Next;
          P->Next = t->Next;
          free(t);
          printf("%s is deleted from list Heads[%d]\n", Key, Pos);
          return true;
     }
}

练习6.1 邻接矩阵存储图的深度优先遍历

#include<stdio.h>
#include<stdlib.h>

#define  MaxVertexNum  1000
#define ERROR -1
typedef enum {false, true} bool;
typedef int Vertex;
typedef Vertex ElementType;

typedef int Position;
struct QNode {
	ElementType *Data;
	Position Front, Rear;
	int MaxSize;
};
typedef struct QNode *Queue;

Queue CreateQueue( int MaxSize ){
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
	Q->Front = Q->Rear = -1;
	Q->MaxSize = MaxSize;
	return Q;
}

bool IsFull( Queue Q ){
	return ((Q->Rear+1)%Q->MaxSize == Q->Front);
}

bool AddQ( Queue Q, ElementType X ){
	if ( IsFull(Q) ) {
		printf("队列满");
		return false;
	}
	else {
		Q->Rear = (Q->Rear+1)%Q->MaxSize;
		Q->Data[Q->Rear] = X;
		return true;
	}
}

bool IsEmpty( Queue Q ){
	return (Q->Front == Q->Rear);
}

ElementType DeleteQ( Queue Q ){
	if ( IsEmpty(Q) ) { 
		printf("队列空");
		return ERROR;
	}
	else  {
		Q->Front =(Q->Front+1)%Q->MaxSize;
		return  Q->Data[Q->Front];
	}
} 

typedef struct ENode *PtrToENode;
struct ENode{
    Vertex V1, V2;
};
typedef PtrToENode Edge;


typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
	Vertex AdjV;		
	PtrToAdjVNode Next;	
};

typedef struct Vnode{
	PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

typedef struct GNode *PtrToGNode;
struct GNode{  
	int Nv;
	int Ne;
	AdjList G;
};
typedef PtrToGNode LGraph;

#define SIX 6
int Visited[MaxVertexNum];

LGraph CreateGraph( int VertexNum ){ 
    Vertex V;
	LGraph Graph;
    
    Graph = (LGraph)malloc( sizeof(struct GNode) ); 
	Graph->Nv = VertexNum;
    Graph->Ne = 0;
   	for (V=0; V<Graph->Nv; V++)
		Graph->G[V].FirstEdge = NULL;
			
	return Graph; 
}
       
void InsertEdge( LGraph Graph, Edge E ){
    PtrToAdjVNode NewNode;
    
    NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode->AdjV = E->V2;
	NewNode->Next = Graph->G[E->V1].FirstEdge;
	Graph->G[E->V1].FirstEdge = NewNode;
		
    NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode->AdjV = E->V1;
	NewNode->Next = Graph->G[E->V2].FirstEdge;
	Graph->G[E->V2].FirstEdge = NewNode;
}

LGraph BuildGraph(){
	LGraph Graph;
	Edge E;
	int Nv, i;
	
	scanf("%d", &Nv);
	Graph = CreateGraph(Nv); 
	
	scanf("%d", &(Graph->Ne));
	if ( Graph->Ne != 0 ) {
	    E = (Edge)malloc( sizeof(struct ENode) );
	    for (i=0; i<Graph->Ne; i++) {
		    scanf("%d %d", &E->V1, &E->V2); 
			E->V1--; E->V2--;
            InsertEdge( Graph, E );
		}
	} 

	return Graph;
} 

void InitializeVisited( int Nv ){
	Vertex V;
	for ( V=0; V<Nv; V++ )
		Visited[V] = false;
}

int SDS_BFS( LGraph Graph, Vertex S ){
	Queue Q;
	Vertex V, Last, Tail;
	PtrToAdjVNode W;
	int Count, Level;

	Q = CreateQueue( MaxVertexNum );
	Visited[S] = true; 
	Count = 1;
	Level = 0;
	Last = S;
    AddQ (Q, S);
    
	while ( !IsEmpty(Q) ) {
		V = DeleteQ(Q);
		for( W=Graph->G[V].FirstEdge; W; W=W->Next ) {
			if ( !Visited[W->AdjV] ) {
				Visited[W->AdjV] = true;
				Count++;
				Tail = W->AdjV;
                AddQ (Q, W->AdjV);
			}
		}
		if ( V==Last ) {
			Level++;
			Last = Tail;
		}
		if ( Level==SIX ) break;
	}
	return Count;
}

void Six_Degrees_of_Separation( LGraph Graph ) {
	Vertex V;
	int count;

	for( V=0; V<Graph->Nv; V++ ) {
		InitializeVisited( Graph->Nv );
		count = SDS_BFS( Graph, V );
		printf("%d: %.2f%%\n", V+1, 100.0*(double)count/(double)Graph->Nv);
	}
}

int main(){
	LGraph G = BuildGraph();
	Six_Degrees_of_Separation(G);
	return 0;
}

练习6.2 邻接表存储图的广度优先遍历

typedef Vertex ElementType;
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode {
	ElementType *Data;     /* 存储元素的数组 */
	Position Front, Rear;  /* 队列的头、尾指针 */
	int MaxSize;           /* 队列最大容量 */
};
typedef PtrToQNode Queue; 

Queue CreateQueue( int MaxSize ){
	Queue Q = (Queue)malloc(sizeof(struct QNode));
	Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
	Q->Front = Q->Rear = 0;
	Q->MaxSize = MaxSize;
	return Q;
}

bool IsFull( Queue Q ){
	return ((Q->Rear+1)%Q->MaxSize == Q->Front);
}

bool AddQ( Queue Q, ElementType X ){
	if ( IsFull(Q) ) {
		printf("队列满");
		return false;
	}
	else {
		Q->Rear = (Q->Rear+1)%Q->MaxSize;
		Q->Data[Q->Rear] = X;
		return true;
	}
}

bool IsEmpty( Queue Q ){
	return (Q->Front == Q->Rear);
}

#define ERROR -1
ElementType DeleteQ( Queue Q ){
	if ( IsEmpty(Q) ) { 
		printf("队列空");
		return ERROR;
	}
	else  {
		Q->Front =(Q->Front+1)%Q->MaxSize;
		return  Q->Data[Q->Front];
	}
}

void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ){
		Queue Q; 	
		Vertex V;
		PtrToAdjVNode W;
	
		Q = CreateQueue( MaxVertexNum );
		Visit( S );
		Visited[S] = true;
	    AddQ(Q, S);
	    
		while ( !IsEmpty(Q) ) {
			V = DeleteQ(Q);
			for( W=Graph->G[V].FirstEdge; W; W=W->Next )
				if ( !Visited[W->AdjV] ) {
					Visit( W->AdjV );
					Visited[W->AdjV] = true;
	                AddQ(Q, W->AdjV);
				}
		} 
}
### PTA 浙大数据结构学习与题目指导 第2 中的函数 #### 线性探测法的查找函数 线性探测法是一种解决哈希冲突的技术,在开放地址法中应用广泛。当发生碰撞时,线性探测会依次检查下一个位置直到找到空槽或目标键值为止。对于此方法的具体实现[^1]: ```c int Search(int H[], int m, KeyType K){ int i = Hash(K); // 计算初始散列地址 while (H[i] != NULLKEY && H[i]!=K){ i=(i+1)%m; // 探测下一地址 } return i; } ``` 该算法通过不断尝试相邻的位置来处理冲突问。 #### 判断是否为二叉搜索树 给定一棵二叉树,判断其是否满足二叉搜索树性质是一个经典问。具体来说就是验证左子树上的所有节点都小于根节点而右子树上所有的节点都要大于等于根节点。下面给出了一种递归解决方案[^2]: ```c bool IsBST(BinTree T) { static ElementType LastData = -INFINITY; if (!T) return true; if (!IsBST(T->Left)) return false; if (LastData > T->Data) return false; LastData = T->Data; return IsBST(T->Right); } ``` 这段代码利用静态变量`LastData`保存最近访问过的结点的数据,并确保遍历过程中始终维持升序关系。 #### 寻找两个有序序列的中位数 为了求解这个问,可以先将两个已排序好的数组合并成一个新的有序数组,再从中选取中间位置处的元素作为最终结果。这里采用堆排序的方式来进行排序操作[^3]: ```cpp double Median(vector<int>& nums1, vector<int>& nums2) { priority_queue<int> pq(nums1.begin(), nums1.end()); for(auto& num : nums2) pq.push(num); int n = pq.size(); double median; if(n % 2 == 0){ for(int i=0;i<n/2-1;++i)pq.pop(); median = ((double)(pq.top()) + (double)(pq.top())) / 2.0; }else{ for(int i=0;i<(n-1)/2;++i)pq.pop(); median=pq.top(); } return median; } ``` 上述三种类型的练习有助于加深读者对不同数据结构及其应用场景的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

少侠PSY

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

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

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

打赏作者

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

抵扣说明:

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

余额充值