PTA数据结构习题(浙江大学)

感谢疫情期间PTA开放免费练习,趁着这个机会补一下数据结构的代

1. 实验11-2-2 学生成绩链表处理(得20/满分20)

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

struct stud_node {
	int    num;
	char   name[20];
	int    score;
	struct stud_node *next;
};

struct stud_node *createlist();
struct stud_node *deletelist(struct stud_node *head, int min_score);

int main()
{
	int min_score;
	struct stud_node *p, *head = NULL;

	head = createlist();
	scanf("%d", &min_score);
	head = deletelist(head, min_score);
	for (p = head; p != NULL; p = p->next)
		printf("%d %s %d\n", p->num, p->name, p->score);

	system("pause");
	return 0;
}

/* 你的代码将被嵌在这里 */
struct stud_node *createlist()
{
	struct stud_node* phead = (struct stud_node*)malloc(sizeof(struct stud_node));//头结点
	struct stud_node* ppre = phead;
	int num, score;
	char name[20];
	scanf("%d", &num);
	while (num)
	{
		scanf("%s %d", name, &score);
		stud_node* p = (struct stud_node*)malloc(sizeof(struct stud_node));
		p->num = num;
		strcpy(p->name, name);
		p->score = score;
		p->next = NULL;
		ppre->next = p;
		ppre = p;
		memset(name, 0, sizeof(name)); // 清空字符数组用于下一次读取
		scanf("%d", &num);
	}
	return phead;
}

struct stud_node *deletelist(struct stud_node *head, int min_score)
{
	if (head == NULL) return NULL;
	struct stud_node* node = head;
	struct stud_node* pre = head;
	struct stud_node* toBeDeleted = NULL;
	while (node != NULL)
	{
		// 删除节点
		if (node->score < min_score)
		{
			// 删除的是头结点
			if (node == head)
			{
				head = head->next;
				toBeDeleted = node;
				node = node->next;
			}
			// 不是头结点
			else
			{
				pre->next = node->next;
				toBeDeleted = node;
				node = node->next;
			}
			free(toBeDeleted);
		}
		else
		{
			pre = node;
			node = node->next;
		}
	}

	return head;
}

2. 习题1.8 二分查找(20分/20分)

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

#define MAXSIZE 10
#define NotFound 0
typedef int ElementType;

typedef int Position;
typedef struct LNode *List;
struct LNode {
	ElementType Data[MAXSIZE];
	Position Last; /* 保存线性表中最后一个元素的位置 */
};

List ReadInput(); /* 裁判实现,细节不表。元素从下标1开始存储 */
Position BinarySearch(List L, ElementType X);

int main()
{
	List L;
	ElementType X;
	Position P;

	L = ReadInput();
	scanf("%d", &X);
	P = BinarySearch(L, X);
	printf("%d\n", P);

	return 0;
}

/* 你的代码将被嵌在这里 */
Position BinarySearch(List L, ElementType X)
{
	// 先找出中间元素
	int left = 0, right = L->Last;
	Position mid;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (L->Data[mid] == X)
			return mid;
		else if (L->Data[mid] > X)
			right = mid - 1;
		else if (L->Data[mid] < X)
			left = mid + 1;
	}
	return NotFound;
}

3. 习题1.9 有序数组的插入

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

#define MAXSIZE 10
typedef enum { false, true } bool;
typedef int ElementType;

typedef int Position;
typedef struct LNode *List;
struct LNode {
	ElementType Data[MAXSIZE];
	Position Last; /* 保存线性表中最后一个元素的位置 */
};

List ReadInput(); /* 裁判实现,细节不表。元素从下标0开始存储 */
void PrintList(List L); /* 裁判实现,细节不表 */
bool Insert(List L, ElementType X);

int main()
{
	List L;
	ElementType X;

	L = ReadInput();
	scanf("%d", &X);
	if (Insert(L, X) == false)
		printf("Insertion failed.\n");
	PrintList(L);

	return 0;
}

/* 你的代码将被嵌在这里 */
bool Insert(List L, ElementType X)
{
	// 数组是降序排列
	Position left = 0, right = L->Last, mid;
	// 判断数组是否已满
	if (right == MAXSIZE - 1) return false;
	// 二分查找寻找插入位置
	if (X < L->Data[right])
	{
		InsertElement(L, right+1, X);
		return true;
	}
	else if (X > L->Data[left])
	{
		InsertElement(L, 0, X);
		return true;
	}
	else
	{
		while (left <= right)
		{
			mid = (left + right) / 2;
			if (X == L->Data[mid]) return false;
			else if (X > L->Data[mid])
			{
				right = mid - 1;
			}
			else if (X < L->Data[mid])
			{
				left = mid + 1;
			}
		}
		InsertElement(L, mid + 1, X);
        return true;
	}
	
}

void InsertElement(List L, int index, ElementType X)
{
	int length = L->Last;
	if (index > length)
	{
		L->Data[index] = X;
		L->Last += 1;
	}
	else
	{
		for (int i = L->Last; i >= index; i--)
		{
			L->Data[i + 1] = L->Data[i];
		}
		L->Data[index] = X;
		L->Last += 1;
	}
}

4. 习题2.4 递增的整数序列链表的插入

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

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表 */

List Insert( List L, ElementType X );

int main()
{
    List L;
    ElementType X;
    L = Read();
    scanf("%d", &X);
    L = Insert(L, X);
    Print(L);
    return 0;
}

/* 你的代码将被嵌在这里 */
List Insert( List L, ElementType X )
{
    // L是头结点,无信息
    List head = L;
    // 构造一个新节点,用于等下插入
    List pNew = (List)malloc(sizeof(struct Node));
    pNew->Data = X;
    pNew->Next = NULL;
    // 空链表
    if(L->Next == NULL)
    {
        head->Next = pNew;
        return head;
    }
    // 两个指针用于寻找插入位置
    List pre = head;
    List node = L->Next;
    while(X > node->Data)
    {
        pre = node;
        node = node->Next;
        if(node->Next == NULL) // 末尾
        {
            node->Next = pNew;
            return head;
        }
    }
    pNew->Next = node;
    pre->Next = pNew;
    return head;
}

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

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

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
	ElementType Data;
	PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 */
void Print(List L); /* 细节在此不表;空链表将输出NULL */

List Merge(List L1, List L2);

int main() {
	List L1, L2, L;
	L1 = Read();
	L2 = Read();
	L = Merge(L1, L2);
	Print(L);
	Print(L1);
	Print(L2);
	system("pause");
	return 0;
}

List Read() {
	List r, L = (struct Node*)malloc(sizeof(struct Node));
	L->Next = NULL;
	r = L;
	int n;
	scanf("%d", &n);
	while (n--) {///尾插法
		Node *p = (struct Node*)malloc(sizeof(struct Node));
		scanf("%d", &p->Data);
		p->Next = NULL;
		r->Next = p;
		r = p;
	}
	return L;
}

List Merge(List L1, List L2) {
	// 新链表的头结点
	List head = (List)malloc(sizeof(struct Node));
	List node = head;
	// 直接用L1/L2遍历链表,先让L1/L2指向首节点
	List p1, p2;
	p1 = L1->Next;
	p2 = L2->Next;
	while (p1 && p2)
	{
		if (p1->Data >= p2->Data)
		{
			node->Next = p2;
			node = p2;
			p2 = p2->Next;
		}
		else
		{
			node->Next = p1;
			node = p1;
			p1 = p1->Next;
		}
	}
	// L2结束,L1还未结束
	if (p1)
	{
		node->Next = p1;
	}
	// L1结束,L2还未结束
	if (p2)
	{
		node->Next = p2;
	}
	L1->Next = NULL;
	L2->Next = NULL;

	return head;
}

void Print(List L) {
	if (L->Next) {
		List r = L;
		while (r->Next) {
			r = r->Next;
			printf("%d ", r->Data);
		}
		puts("");
	}
	else {
		printf("NULL\n");
	}
}
  • 8
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值