南京邮电大学数据结构与算法实验1(教材p216 15题)

南京邮电大学数据结构与算法实验1(教材p216 1~5题)

1.顺序表的初始化、查找、插入、删除、输出、撤销等操作

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

typedef struct vector {
    int size, count;
    int* data;
} vector;

//得到初始化的指定大小的顺序表
vector* getNewVector(int n) {
    vector* p = (vector*)malloc(sizeof(vector));
    p->size = n;
    p->count = 0;
    p->data = (int*)malloc(sizeof(int) * n);
    return p;
}

//扩容顺序表大小
int expand(vector* v) {
    if (v == NULL) return 0;
    printf("expand v from %d to %d\n", v->size, 2 * v->size);
    int* p = (int*)realloc(v->data, sizeof(int) * 2 * v->size);
    if (p == NULL) return 0;
    v->data = p;
    v->size *= 2;
    return 1;
}

//在顺序表的指定位置插入指定值元素
int insert(vector* v, int pos, int val) {
    if (pos < 0 || pos > v->count) return 0;
    if (v->size == v->count && !expand(v)) return 0;
    for (int i = v->count - 1; i >= pos; i--) {
        v->data[i + 1] = v->data[i];
    }
    v->data[pos] = val;
    v->count += 1;
    return 1;
}

//删除顺序表的一个指定位置的元素
int erase(vector* v, int pos) {
    if (pos < 0 || pos >= v->count) return 0;
    for (int i = pos + 1; i < v->count; i++) {
        v->data[i - 1] = v->data[i];
    }
    v->count -= 1;
    return 1;
}

//输出顺序表的值
void output_vector(vector* v) {
    int len = 0;
    for (int i = 0; i < v->size; i++) {
        len += printf("%3d", i);
    }
    printf("\n");
    for (int i = 0; i < len; i++) printf("-");
    printf("\n");
    for (int i = 0; i < v->count; i++) {
        printf("%3d", v->data[i]);
    }
    printf("\n");
    printf("\n\n");
    return;
}

//撤销顺序表
void clear(vector* v) {
    if (v == NULL) return;
    free(v->data);
    free(v);
    return;
}
//新颖的测试函数
int main() {
    srand(time(0));
#define MAX_OP 20
    vector* v = getNewVector(2);
    for (int i = 0; i < MAX_OP; i++) {
        int op = rand() % 4, pos, val, ret;
        switch (op) {
        case 0:
        case 1:
        case 2:
            pos = rand() % (v->count + 2);
            val = rand() % 100;
            ret = insert(v, pos, val);
            printf("insert %d at %d to vector = %d\n",
                val, pos, ret);
            break;
        case 3:
            pos = rand() % (v->count + 2);
            ret = erase(v, pos);
            printf("erase item at %d in vector = %d\n",
                pos, ret);
            break;
        }
        output_vector(v);
    }
    clear(v);
    return 0;
}

2. 编写程序,完成带表头结点单链表的初始化、查找、插入、删除、输出、撤销等操作

3. 编写程序实现单链表的逆置操作

4. 编写程序实现将单链表排序成为有序单链表的操作

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

typedef struct Node {
	int data;
	struct Node* next;
};

typedef struct HeaderList {
	Node* head;
	int n;
};

//有头链表初始化
HeaderList* init_HeaderList() {
	HeaderList* l = (HeaderList*)malloc(sizeof(HeaderList));
	l->head = (Node*)malloc(sizeof(Node));
	l->head->next = NULL;
	l->n = 0;
	return l;
}

//判断有头链表中有没有指定值的元素,有返回1,没有返回0
int find(HeaderList* l, int val) {
	if (l == NULL) return -1;
	Node* p;
	for (p = l->head->next; p != NULL; p = p->next) {
		if (p->data == val) return 1;
	}
	return 0;
}

//头插法
void insert(HeaderList* l, int val) {
	if (l == NULL) return;
	Node* p = (Node*)malloc(sizeof(Node));
	p->data = val;
	p->next = l->head->next;
	l->head->next = p;
	return;
}

//删除有头链表中指定位置的元素(规定头节点后面的那个节点pos=0)
void erase(HeaderList* l, int pos) {
	if (l == NULL) return;
	Node* p = l->head->next;
	Node* q = l->head;
	for (int i = 0; i < pos;i++) {
		p = p->next;
		q = q->next;
	}
	q->next = p->next;
	free(p);
	return;
}

//撤销有头链表
void clear(HeaderList* l) {
	if (l == NULL) return;
	free(l->head);
	free(l);
	return;
}

//输出有头链表的值
void output(HeaderList* l) {
	if (l == NULL) return;
	Node* p;
	printf("此链表为:\n");
	for (p = l->head->next; p != NULL; p = p->next) {
		printf("%3d ", p->data);
	}
	return;
}

//冒泡排序(值从小到大)
void sort(HeaderList* l) {
	if (l == NULL) return;
	Node* p, * q;
	for (p = l->head->next; p != NULL; p = p->next) {
		for (q = p->next; q != NULL; q = q->next) {
			if (p->data > q->data) {
				int temp = p->data;
				p->data = q->data;
				q->data = temp;
			}
		}
	}
	return;
}

//逆置(采用递归的方法)
//head = l->head
Node* reverse(Node* head) {
	if (head == NULL || head->next == NULL) return head;
	Node* new_head,*tail;
	tail = head->next;
	new_head = reverse(head->next);
	head->next = tail->next;
	tail->next = head;
	return new_head;
}
//测试用例
int main(void) {
	HeaderList* myList = init_HeaderList(); // 初始化头链表

	// 在链表中插入元素
	insert(myList, 10);
	insert(myList, 20);
	insert(myList, 30);
	insert(myList, 40);

	// 输出链表内容
	output(myList);

	// 查找元素
	int valToFind = 20;
	int found = find(myList, valToFind);
	if (found) {
		printf("\n%d 在链表中找到了。\n", valToFind);
	}
	else {
		printf("\n%d 在链表中未找到。\n", valToFind);
	}

	// 删除元素
	int posToRemove = 2; // 删除第3个元素
	erase(myList, posToRemove);
	printf("\n删除第%d个元素后的链表:\n", posToRemove+1);
	output(myList);

	// 冒泡排序
	printf("\n进行冒泡排序后的链表:\n");
	sort(myList);
	output(myList);

	// 逆置链表
	printf("\n逆置链表后的结果:\n");
	myList->head->next = reverse(myList->head->next);
	output(myList);

	// 释放内存
	clear(myList);

	return 0;
}

5.编写程序实现一元多项式的创建、输出、撤销以及两个一元多项式相加和相乘的操作

/*
@created by pzr
@created at 2023-9-29
用链表解决多项式运算问题
*/
#define _CRT_SECURE_NO_WARNINGS	
#include <stdio.h>
#include <stdlib.h>
#include <time.h>


//定义链表结构
typedef struct poly {
	int coef;
	int exp;
	struct poly* next;
}poly;

//使用头节点
typedef struct Polynominal {
	poly* head;
}Polynominal;

//定义创建新节点的功能(重载)
poly* getNewNode(int coef, int exp) {
	poly* p = (poly*)malloc(sizeof(poly));
	p->coef = coef;
	p->exp = exp;
	p->next = NULL;
	return p;
}

//对用户输入的乱序项进行排序(按照指数大小从大到小排列)
void sort(Polynominal* m) {
	poly* p, * q, * temp = (poly*)malloc(sizeof(poly));
	for (p = m->head->next; p != NULL; p = p->next) {
		for (q = p->next; q != NULL; q = q->next) {
			if (p->exp < q->exp) {
				// 交换节点
				temp->exp = p->exp;
				p->exp = q->exp;
				q->exp = temp->exp;
				temp->coef = p->coef;
				p->coef = q->coef;
				q->coef = temp->coef;

			}
		}
	}
}

//定义创建多项式结构的功能
Polynominal* create_polynominal() {
	Polynominal* p = (Polynominal*)malloc(sizeof(Polynominal));
	p->head = getNewNode(-1, -1);
	poly* head, * tail;
	head = p->head;
	tail = p->head;
	printf("请输入一个多项式(通过指定指数为-1来结束输入)\n");
	do {
		int coef = 0;
		int exp = 0;
		printf("请输入系数:\n");
		scanf("%d", &coef);
		printf("请输入指数:\n");
		scanf("%d", &exp);
		//如果输入无效项,直接退出构造
		if (exp < 0) break;
		//如果输入有效项,则直接插入此多项式
		poly* p1 = getNewNode(coef, exp);
		tail->next = p1;
		tail = p1;
	} while (1);
	//按指数大小从大到小排列
	sort(p);
	return p;
}

//输出当前多项式(测试用)
void print(Polynominal* p) {
	poly* q;
	for (q = p->head->next; q != NULL; q = q->next) {
		if (q->next == NULL) {
			printf("%d*x^%d", q->coef, q->exp);
		}
		else {
			printf("%d*x^%d+", q->coef, q->exp);
		}
	}
	printf("\n\n");
}

//实现多项式相加功能
Polynominal* add(Polynominal* p1, Polynominal* p2) {
	Polynominal* result = (Polynominal*)malloc(sizeof(Polynominal));
	result->head = getNewNode(-1, -1); // 初始化结果多项式的头节点
	poly* current1 = p1->head->next;
	poly* current2 = p2->head->next;
	poly* currentResult = result->head;

	while (current1 != NULL && current2 != NULL) {
		if (current1->exp > current2->exp) {
			currentResult->next = getNewNode(current1->coef, current1->exp);
			current1 = current1->next;
		}
		else if (current1->exp < current2->exp) {
			currentResult->next = getNewNode(current2->coef, current2->exp);
			current2 = current2->next;
		}
		else { // 当两项的指数相等时
			int sumCoefficients = current1->coef + current2->coef;
			if (sumCoefficients != 0) {
				currentResult->next = getNewNode(sumCoefficients, current1->exp);
			}
			current1 = current1->next;
			current2 = current2->next;
		}
		currentResult = currentResult->next;
	}

	// 将未处理完的项添加到结果多项式中
	while (current1 != NULL) {
		currentResult->next = getNewNode(current1->coef, current1->exp);
		current1 = current1->next;
		currentResult = currentResult->next;
	}

	while (current2 != NULL) {
		currentResult->next = getNewNode(current2->coef, current2->exp);
		current2 = current2->next;
		currentResult = currentResult->next;
	}

	return result;
}


//实现多项式相乘功能
Polynominal* multiply(Polynominal* p1, Polynominal* p2) {
	Polynominal* result = (Polynominal*)malloc(sizeof(Polynominal));
	result->head = getNewNode(-1, -1); // 初始化结果多项式的头节点
	poly* current1 = p1->head->next;

	while (current1 != NULL) {
		poly* current2 = p2->head->next;
		poly* tempResult = result->head;

		while (current2 != NULL) {
			int productCoefficient = current1->coef * current2->coef;
			int productExponent = current1->exp + current2->exp;

			// 查找是否已存在相同指数的项
			while (tempResult->next != NULL && tempResult->next->exp > productExponent) {
				tempResult = tempResult->next;
			}

			if (tempResult->next != NULL && tempResult->next->exp == productExponent) {
				// 如果找到相同指数的项,将系数相加
				tempResult->next->coef += productCoefficient;
			}
			else {
				// 否则插入新项
				poly* newTerm = getNewNode(productCoefficient, productExponent);
				newTerm->next = tempResult->next;
				tempResult->next = newTerm;
			}

			current2 = current2->next;
		}

		current1 = current1->next;
	}

	return result;
}

//测试用例
int main(void) {
	Polynominal* p1 = create_polynominal();
	printf("请输入第2个多项式:\n");
	Polynominal* p2 = create_polynominal();
	Polynominal* p3 = add(p1, p2);
	printf("相加结果为:\n");
	print(p3);
	Polynominal* p4 = multiply(p1, p2);
	printf("相乘结果为:\n");
	print(p4);
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值