广东财经大学考研初试数据结构历年真题分类参考答案:排序

98 阅读6分钟

选择题

[2024年第2题]:A [2023年第9题]:A [2023年第10题]:D [2021年第17题]:A [2021年第18题]:D [2021年第19题]:D [2021年第20题]:D [2020年第10题]:C [2019年第9题]:B

填空题

[2021年第5题]:稳定 相邻

[2019年第9题]:稳定

[2019年第10题]:40,38,46,56,79,84

名词解释

[2022年第7、10题]:

归并排序:将整个数组平均分为两部分,然后分别对两部分进行归并排序,然后按照递增或者递减的顺序合并两个子数组。

基数排序:

简答题

[2023年第5题]:

(1)

屏幕截图 2025-06-06 181053.jpg

(2) 快速排序在每一趟排序后都能将记录序列均匀地分割成两个长度大致相等的子列表。(我没理解,靠的记忆) 最好时间复杂度:

Nlog2N N{\log_2^{N}}

(3)选择基准值的时候,可以从待排序序列的第一个元素,最后一个元素,中间位置元素中选择中间值作为基准值。

[2022年第2题]: (1)35 17 11 28 12 41 75 15 96 58 81 94 95 (2)28 12 11 35 15 41 58 17 94 75 81 96 95

[2022年第6题]:

(1)第6000大即从大到小排序的话,第6000个元素。如果按照从小到大排序就是第4001个元素。 假设存储数据的数组下标从1开始,如果存储数据的数组下标是从0开始,就将下标为0的元素放到数组末尾。 首先,利用数组建立小根堆,然后将堆顶元素与数组下标为10000的元素互换位置,再对新堆顶元素进行筛选操作,即保证堆仍然是小根堆。得到新的小根堆之后,再将堆顶元素与数组下标为9999的元素互换位置,再对新堆顶元素进行筛选操作,保证堆仍然是小根堆。以此类推,直到将堆顶元素与下标为6001的元素互换位置,再对堆顶元素进行筛选操作,得到新的小根堆。此时堆顶元素即按从小到大排列的第4001个元素,即第6000大的数。

(2)假设存储数据的数组下标从1开始,如果存储数据的数组下标是从0开始,就将下标为0的元素放到数组末尾。

  1. 建立大根堆,
  2. 将堆顶元素与数组下标为10000的元素互换位置,将堆顶元素进行筛选操作,使之成为大根堆,新的堆顶元素即为第2大。
  3. 将堆顶元素与数组下标为9999的元素互换位置,将堆顶元素进行筛选操作,使之成为大根堆,新的堆顶元素即为第3大。
  4. 类似地,继续进行上述操作,直到堆顶元素与数组下标为7002的元素互换位置,将堆顶元素进行筛选操作,使之成为大根堆,此时堆顶元素即为第3000大,此时开始记录每次得到的新堆顶元素,...,堆顶元素与下标为4002的元素交换,得到新的堆顶元素,再进行筛选操作,此时堆顶元素即为第6000大。 至此就找到了第3000大到第6000大的元素。

[2021年分析计算题第4题]:

(1)堆排序利用数组元素在逻辑上构成完全二叉树的思想实现。 DataStructure-GDEF_PostGraduate_Exam_2021_3_4_1.png

对本题的关键字序列初始建堆的结果:[93,75,60,54,36,49,27]

(2)采取顺序存储结构。不稳定。

(3)小顶堆。

[2020年第6题]

(1)DataStructure-GDEF_PostGraduate_Exam_2020_3_6_1

(2)DataStructure-GDEF_PostGraduate_Exam_2020_3_6_2

[2019年综合应用题第6题]

(1)小根堆

(2)见[2020年第6题] (1)

(3)见[2020年第6题] (2)

算法设计与编程

[2020年第4题].

void BubbleSort(SqList &L) {
    for (int i = 1; i <= L.length - 2; i++) {    //趟数
        for (int j = 1; j <= L.length -1-i; j++) { //使用j来对L.arr中的相邻元素进行比较
            if (L.arr[j].key > L.arr[j + 1].key) {
                RecordType tmp = L.arr[j + 1];
                L.arr[j + 1] = L.arr[j];
                L.arr[j] = tmp; 
            }
        }
    }
}

[2019年第4题].

(1)

使用双指针,low指向第一个元素,high指向最后一个元素。

情况一,如果low<high,L.r[high].key<0且L.r[low].key>=0,则交换L.r[high].key与L.r[low].key的值,low++,high--。

情况二:在保证low<high的前提下,如果L.r[high].key>=0,则high--。

情况三:在保证low<high的前提下,如果L.r[low].key<0,则low++。

(2)

void Process(SqList L) {
    int low = 1;
    int high = L.length - 1;
    while (low < high) {
        while (low < high && L.r[high].key >= 0) {
            high--;
        }
        while (low < high && L.r[low].key < 0) {
            low++;
        }
        if (low < high) {
            L.r[0] = L.r[high];
            L.r[high] = L.r[low];
            L.r[low] = L.r[0];
        }
    }
}

综合题

[2023年第3题].

(1)

typedef struct {
    int no;
    char name[10];
    float chinese;
    float maths;
    float english;
   	float score;
}StudentGrade;

typedef struct {
    StudentGrade arr[100]; 	//存储所有学生成绩
    int stuNums;	//学生总数
}GradeList;   

(2)采用的排序算法应具有稳定性,能实现降序排列的特点。例如:归并排序算法。

(3)

StudentGrade[100] tmp = (StudentGrade *)malloc(100 * sizeof(StudentGrade));
//计算每个学生的总分score
void calculateScore(GradeList &L) {
    for (i = 0; i < L.stuNums; i++) {
        L.arr[i].score = L.arr[i].chinese + L.arr[i].maths + L.arr[i].english
    }
}

void merge(GradeList &L, int left, int mid, int right) {
	//将两个非递增排序的数组合并为一个数组
	int LPtr = left;
	int leftPtr = left;
	int rightPtr = mid+1;
	for(int i = left; i<= right; i++){
		tmp[i] = L.arr[i];
	}
	while(leftPtr <= mid && rightPtr <= right) {
		if(tmp[leftPtr].score >= tmp[rightPtr].score) {
			L.arr[LPtr++] = tmp[leftPtr++];
		} else if(tmp[leftPtr].score < tmp[rightPtr].score) {
			L.arr[LPtr++]  =tmp[rightPtr++];
		}
	}
	while(leftPtr > mid && rightPtr <=right) {
		L.arr[LPtr++] = tmp[rightPtr++];
	} 
	while(leftPtr <= mid && rightPtr > right) {
		L.arr[LPtr++] = tmp[leftPtr++];
	}
	
}

void sort(GradeList &L int left, int right) {
    int mid = left + (right - left) / 2;
    if(left >= right) {
        return;
    }
    sort(L, left, mid);
    sort(L, mid+1, right);
    merge(L, left, right);
}

//按照非递增顺序对学生成绩排序
void mergeSort(GradeList &L) {
	calculateScore(L);
    sort(L,0, L.stuNums-1);
}

(4)二分查找,由于学生已经按照总分进行排序,二分查找算法运行过程中,不断把待查找的学生数量减小一半,时间复杂度为log2Nlog_2^N;若遇到学生总分重复的情况,则查找到其中一条数据后,再往上下遍历找到剩余相同总分的学生。


/**
	tarScore: 目标分数
	返回总分等于tarScore对应同学在成绩表中的位置;若未找到,则返回-1
**/
int binarySearch(GradeList &list, int tarScore, int l, int r) {
	if(l > r) return -1;
	int mid = l+(r-l)/2;
	if(list.arr[mid].score == tarScore) return mid;
	if(list.arr[mid].score < tarScore) {
		l = mid + 1;
	} else if(list.arr[l+(r-l)/2].score > tarScore) {
		r = mid - 1;
	}
	return binarySearch(list, tarScore, l, r);
}

vector Search(GradeList &list, int targetScore) {
	vector<int> stuIdx;
	vector<StudentGrade> res;
	int idx = binarySearch(list, targetScore, 0, list.stuNums - 1);
	//遍历排序后成绩表中idx前后的同学成绩,
	stuIdx.push_back(idx);
	if(idx == -1) {
		printf("未找到相应记录");
		return res;
	}
	int tmp = idx-1;
	while(tmp >=0 && list.arr[tmp].score == targetScore) {
		stuIdx.push_back(tmp);
		tmp--;
	}
	tmp = idx+1;
	while(tmp < list.stuNums && list.arr[tmp].score == targetScore) {
		stuIdx.push_back(tmp);
		tmp++;
	}
	for(int i = 0; i < stuIdx.size(); i++) {
		res.push_back(list.arr[stuIdx[i]]);
	}
	return res;
}