桂 林 理 工 大 学
实 验 报 告
一、实验名称
实验1 顺序表
二、实验内容:
1.将书中介绍的顺序表的基本算法(如初始化、求长度、插人、删除、输出等)汇总在一起,用一个完整的程序实现顺序表的基本运算,并且编写顺序表的判空、判满等基本运算的算法。
源码:
#include<stdio.h>
#include<malloc.h>
#define ERROR 0
#define OK 1
#define INIT_SIZE 5 /*初始分配的顺序表长度*/
#define INCREM 5 /*溢出时,顺序表长度的增量*/
typedef int ElemType; /*定义表元素的类型*/
typedef struct Sqlist{
ElemType *slist; /*存储空间的基地址*/
int length; /*顺序表的当前长度*/
int listsize; /*当前分配的存储空间*/
}Sqlist;
int InitList_sq(Sqlist *L); /*初始化一个长度为5的顺序表L*/
int CreateList_sq(Sqlist *L,int n); /*创建一个长度为n的顺序表L*/
int ListInsert_sq(Sqlist *L,int i,ElemType e); /*在顺序表L中插入数据元素:在第i个元素之前插入e*/
int PrintList_sq(Sqlist *L); /*输出顺序表的元素*/
int ListDelete_sq(Sqlist *L,int i); /*删除第i个元素*/
int ListLocate(Sqlist *L,ElemType e); /*查找值为e的元素*/
int InitList_sq(Sqlist *L){
L->slist=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));
if(!L->slist) return ERROR;
L->length=0;
L->listsize=INIT_SIZE;
return OK;
}/*InitList*/
int CreateList_sq(Sqlist *L,int n){
ElemType e;
int i;
for(i=0;i<n;i++){
printf("input data %d:",i+1);
scanf("%d",&e);
if(!ListInsert_sq(L,i+1,e))
return ERROR;
}
return OK;
}/*CreateList*/
/*输出顺序表中的元素*/
int PrintList_sq(Sqlist *L){
int i;
for(i=1;i<=L->length;i++)
printf("%5d",L->slist[i-1]);
return OK;
}/*PrintList*/
int ListInsert_sq(Sqlist *L,int i,ElemType e){
int k;
if(i<1||i>L->length+1)
return ERROR;
if(L->length>=L->listsize){
L->slist=(ElemType*)realloc(L->slist,
(INIT_SIZE+INCREM)*sizeof(ElemType));
if(!L->slist)
return ERROR;
L->listsize+=INCREM;
}
for(k=L->length-1;k>=i-1;k--){
L->slist[k+1]= L->slist[k];
}
L->slist[i-1]=e;
L->length++;
return OK;
}/*ListInsert*/
/*在顺序表中删除第i个元素*/
int ListDelete_sq(Sqlist *L,int i){
}
/*在顺序表中查找指定值元素,返回其序号*/
int ListLocate(Sqlist *L,ElemType e){
}
int main(){
Sqlist sl;
int n,m,k;
printf("please input n:"); /*输入顺序表的元素个数*/
scanf("%d",&n);
if(n>0){
printf("\n1-Create Sqlist:\n");
InitList_sq(&sl);
CreateList_sq(&sl,n);
printf("\n2-Print Sqlist:\n");
PrintList_sq(&sl);
printf("\nplease input insert location and data:(location,data)\n");
scanf("%d,%d",&m,&k);
ListInsert_sq(&sl,m,k);
printf("\n3-Print Sqlist:\n");
PrintList_sq(&sl);
printf("\n");
}
else
printf("ERROR");
return 0;
}
2.请编写一个完整的程序,使用顺序表实现以下任务。
(1)产生50个1~100的随机整数,将其中的偶数依次保存到顺序表中。
(2)输出顺序表的所有元素,并求顺序表的长度。
(3)在顺序表中指定位置i处,插入一个新产生1~100的随机整数。
(4)删除顺序表中值为x的结点或指定位置i的结点。
(5)将顺序表按升序排列,并输出排序结果。
3.学生成绩表包括学号、姓名、数学成绩、英语成绩、平均成绩等字段。建立一个顺序表表示学生成绩表,请编写程序,实现以下任务。
(1)输人学号姓名、数学和英语成绩,直到输人学号为0结束。
(2)统计所有学生的平均成绩,并输出学生成绩表。
(3)插入一个新的学生记录,并将其插人到指定的结点位置。
(4)输入一个学生的学号,在成绩表中查找与输人学号相同的学生结点,若存在该学生记录,则输出其所有信息,否则输出“不存在此学号的学生"信息。
(5)输入一个学生的学号,在成绩表中查找与输人学号相同的学生结点,若存在该学生记录,则将其删除,否则输出“该学生不存在”的信息。
(6)将学生成绩按平均成绩从高到低进行排序,并输出排序结果。
源码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_SIZE 50
// 顺序表结构体定义
typedef struct {
int data[MAX_SIZE];
int length;
} SeqList;
// 初始化顺序表
void initList(SeqList* L) {
L->length = 0;
}
// 获取顺序表长度
int listLength(SeqList L) {
return L.length;
}
// 判断顺序表是否为空
int isEmpty(SeqList L) {
return L.length == 0;
}
// 判断顺序表是否已满
int isFull(SeqList L) {
return L.length == MAX_SIZE;
}
// 在指定位置插入元素
void insert(SeqList* L, int index, int elem) {
if (isFull(*L)) {
printf("顺序表已满。\n");
return;
}
if (index < 0 || index > L->length) {
printf("无效的索引。\n");
return;
}
for (int i = L->length; i > index; i--) {
L->data[i] = L->data[i - 1];
}
L->data[index] = elem;
L->length++;
}
// 删除指定位置的元素
void deleteElem(SeqList* L, int index) {
if (isEmpty(*L)) {
printf("顺序表为空。\n");
return;
}
if (index < 0 || index >= L->length) {
printf("无效的索引。\n");
return;
}
for (int i = index; i < L->length - 1; i++) {
L->data[i] = L->data[i + 1];
}
L->length--;
}
// 输出顺序表的所有元素
void printList(SeqList L) {
printf("顺序表的元素:\n");
for (int i = 0; i < L.length; i++) {
printf("%d ", L.data[i]);
}
printf("\n");
}
// 生成50个1~100的随机整数,保存偶数到顺序表中
void generateRandomEvenNumbers(SeqList* L) {
srand(time(NULL));
for (int i = 0; i < 50; i++) {
int num = rand() % 100 + 1;
if (num % 2 == 0) {
insert(L, L->length, num);
}
}
}
// 将顺序表按升序排列
void sortList(SeqList* L) {
for (int i = 0; i < L->length - 1; i++) {
for (int j = 0; j < L->length - 1 - i; j++) {
if (L->data[j] > L->data[j + 1]) {
int temp = L->data[j];
L->data[j] = L->data[j + 1];
L->data[j + 1] = temp;
}
}
}
}
// 主函数
int main() {
SeqList list;
initList(&list);
// 生成50个1~100的随机偶数,并保存到顺序表中
generateRandomEvenNumbers(&list);
// 输出顺序表的所有元素,并求顺序表的长度
printList(list);
printf("顺序表的长度为:%d\n", listLength(list));
// 在顺序表中指定位置插入一个新产生1~100的随机整数
int randomNum = rand() % 100 + 1;
int insertIndex = 2; // 为示例将在第3个位置插入
insert(&list, insertIndex, randomNum);
// 输出插入后的顺序表
printf("在第%d个位置插入%d后的顺序表:\n", insertIndex + 1, randomNum);
printList(list);
// 删除顺序表中值为x的结点或指定位置i的结点
int deleteIndex = 4; // 为示例删除第5个位置的元素
deleteElem(&list, deleteIndex);
// 输出删除后的顺序表
printf("删除第%d个位置元素后的顺序表:\n", deleteIndex + 1);
printList(list);
// 将顺序表按升序排列
sortList(&list);
// 输出排序后的顺序表
printf("顺序表按升序排列后的结果:\n");
printList(list);
return 0;
}
三、心得体会:
通过学习和实践线性表相关知识,我深刻体会到线性表作为一种基本数据结构,在实际编程中具有重要作用。线性表的顺序存储结构和链式存储结构各有优缺点,可以根据具体需求选择适合的实现方式。通过顺序表的插入、删除、查找等操作,我深入理解了数据在顺序存储结构中的组织与管理方式,加深了对数组使用的认识。而链表的动态性和灵活性使得其在插入、删除操作中更具优势,带给我启发和思考。掌握线性表的操作,不仅提升了编程能力,更培养了逻辑思维和问题解决能力。在今后的学习和工作中,我将深入学习更多数据结构,不断提升自己的编程技能,为解决实际问题提供更多可能性。