《数据结构上机实验(C语言实现)》笔记(2 / 12):线性表

验证性实验

实现顺序表各种基本运算的算法

放码

sqlist.h
#ifndef SQLIST_H
#define SQLIST_H

#define MaxSize 50
typedef char ElemType;
typedef struct
{
   
	ElemType data[MaxSize];		//存放顺序表元素
	int length;					//存放顺序表的长度
} SqList;						//声明顺序表的类型

void CreateList(SqList *&L, ElemType a[], int n); //整体建立顺序表
void InitList(SqList *&L);	//初始化线性表
void DestroyList(SqList *&L);  //销毁线性表
bool ListEmpty(SqList *L);	//判线性表是否为空表
int ListLength(SqList *L);	//求线性表的长度
void DispList(SqList *L);	//输出线性表
bool GetElem(SqList *L, int i, ElemType &e);	//求线性表中第i个元素值
int LocateElem(SqList *L, ElemType e);	//查找第一个值域为e的元素序号
bool ListInsert(SqList *&L, int i, ElemType e);	//插入第i个元素
bool ListDelete(SqList *&L, int i, ElemType &e); //删除第i个元素

#endif
sqlist.cpp
//顺序表运算算法
#include <stdio.h>
#include <malloc.h>
#include "sqlist.h"

void CreateList(SqList * & L, ElemType a[], int n) //整体建立顺序表
{
   
	L = (SqList *)malloc(sizeof(SqList));
	for (int i = 0; i < n; i++)
		L->data[i] = a[i];
	L->length = n;
}

void InitList(SqList * & L) //初始化线性表
{
   
	L = (SqList *)malloc(sizeof(SqList)); //分配存放线性表的空间
	L->length = 0;
}

void DestroyList(SqList * & L) //销毁线性表
{
   
	free(L);
}

bool ListEmpty(SqList * L) //判线性表是否为空表
{
   
	return (L->length == 0);
}

int ListLength(SqList * L) //求线性表的长度
{
   
	return (L->length);
}

void DispList(SqList * L) //输出线性表
{
   
	for (int i = 0; i < L->length; i++)
		printf("%c ", L->data[i]);
	printf("\n");
}

bool GetElem(SqList * L, int i, ElemType & e) //求线性表中第i个元素值
{
   
	if (i < 1 || i > L->length)
		return false;
	e = L->data[i - 1];
	return true;
}

int LocateElem(SqList * L, ElemType e) //查找第一个值域为e的元素序号
{
   
	int i = 0;
	while (i < L->length && L->data[i] != e) i++;
	if (i >= L->length)
		return 0;
	else
		return i + 1;
}

bool ListInsert(SqList * & L, int i, ElemType e) //插入第i个元素
{
   
	int j;
	if (i < 1 || i > L->length + 1)
		return false;
	i--; //将顺序表位序转化为elem下标
	for (j = L->length; j > i; j--) //将data[i]及后面元素后移一个位置
		L->data[j] = L->data[j - 1];
	L->data[i] = e;
	L->length++; //顺序表长度增1
	return true;
}

bool ListDelete(SqList * & L, int i, ElemType & e) //删除第i个元素
{
   
	int j;
	if (i < 1 || i > L->length)
		return false;
	i--; //将顺序表位序转化为elem下标
	e = L->data[i];
	for (j = i; j < L->length - 1; j++) //将data[i]之后的元素前移一个位置
		L->data[j] = L->data[j + 1];
	L->length--; //顺序表长度减1
	return true;
}
exp2-1.cpp
//文件名:exp2-1.cpp
#include "sqlist.h"
#include <stdio.h>

int main()
{
   
	SqList *L;
	ElemType e;
	printf("顺序表的基本运算如下:\n");
	printf("  (1)初始化顺序表L\n");
	InitList(L);

	printf("  (2)依次插入a,b,c,d,e元素\n");
	ListInsert(L,1,'a');
	ListInsert(L,2,'b');
	ListInsert(L,3,'c');
	ListInsert(L,4,'d');
	ListInsert(L,5,'e');
	
	printf("  (3)输出顺序表L:");
	DispList(L);
	
	printf("  (4)顺序表L长度:%d\n",ListLength(L));
	
	printf("  (5)顺序表L为%s\n",(ListEmpty(L)?"空":"非空"));
	
	GetElem(L,3,e);
	printf("  (6)顺序表L的第3个元素:%c\n",e);
	
	printf("  (7)元素a的位置:%d\n", LocateElem(L,'a'));
	
	printf("  (8)在第4个元素位置上插入f元素\n");
	ListInsert(L, 4, 'f');
	
	printf("  (9)输出顺序表L:");
	DispList(L);
	
	printf("  (10)删除L的第3个元素\n");
    ListDelete(L,3,e);
	
	printf("  (11)输出顺序表L:");
	DispList(L);
	
	printf("  (12)释放顺序表L\n");
	DestroyList(L);
	
	return 1;
}

结果

顺序表的基本运算如下:
  (1)初始化顺序表L
  (2)依次插入a,b,c,d,e元素
  (3)输出顺序表L:a b c d e
  (4)顺序表L长度:5
  (5)顺序表L为非空
  (6)顺序表L的第3个元素:c
  (7)元素a的位置:1
  (8)在第4个元素位置上插入f元素
  (9)输出顺序表L:a b c f d e
  (10)删除L的第3个元素
  (11)输出顺序表L:a b f d e
  (12)释放顺序表L
请按任意键继续. . .

实现单链表各种基本运算的算法

放码

linklist.h
#ifndef LINKLIST_H
#define LINKLIST_H

typedef int ElemType;
typedef struct LNode {
   
	ElemType data;
	struct LNode *next; //指向后继结点
}LinkNode; //声明双链表结点类型

void CreateListF(LinkNode *&L, ElemType a[], int n); //头插法建双链表
void CreateListR(LinkNode *&L, ElemType a[], int n); //尾插法建双链表
void InitList(LinkNode *&L); //初始化线性表
void DestroyList(LinkNode *&L); //销毁线性表
bool ListEmpty(LinkNode *L); //判线性表是否为空表
int ListLength(LinkNode *L); //求线性表的长度
void DispList(LinkNode *L); //输出线性表
bool GetElem(LinkNode *L, int i, ElemType &e); //求线性表中第i个元素值
int LocateElem(LinkNode *L, ElemType e); //查找第一个值域为e的元素序号
bool ListInsert(LinkNode *&L, int i, ElemType e); //插入第i个元素
bool ListDelete(LinkNode *&L, int i, ElemType &e); //删除第i个元素

#endif
linklist.cpp
//单链表运算算法
#include <stdio.h>
#include <malloc.h>
#include "linklist.h"

void CreateListF(LinkNode *&L, ElemType a[], int n) //头插法建立单链表
{
   
	LinkNode *s;
	L = (LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
	L->next = NULL;
	for (int i = 0; i < n; i++) {
   
		s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
		s->data = a[i];
		s->next = L->next; //将结点s插在原开始结点之前,头结点之后
		L->next = s;
	}
}

void CreateListR(LinkNode *&L, ElemType a[], int n) //尾插法建立单链表
{
   
	LinkNode *s, *r;
	L = (LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
	L->next = NULL;
	r = L; //r始终指向尾结点,开始时指向头结点
	for (int i = 0; i < n; i++) {
   
		s = (LinkNode *)malloc(sizeof(LinkNode)); //创建新结点s
		s->data = a[i];
		r->next = s; //将结点s插入r结点之后
		r = s;
	}
	r->next = NULL; //尾结点next域置为NULL
}

void InitList(LinkNode *&L) //初始化线性表
{
   
	L = (LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
	L->next = NULL; //单链表置为空表
}

void DestroyList(LinkNode *&L) //销毁线性表
{
   
	LinkNode *pre = L, *p = pre->next;
	while (p != NULL) {
   
		free(pre);
		pre = p; //pre、p同步后移一个结点					
		p = pre->next;
	}
	free(pre); //此时p为NULL,pre指向尾结点,释放它
}

bool ListEmpty(LinkNode *L) //判线性表是否为空表
{
   
	return (L->next == NULL);
}

int ListLength(LinkNode *L) //求线性表的长度
{
   
	int i = 0;
	LinkNode *p = L; //p指向头结点,n置为0(即头结点的序号为0)
	while (p->next != NULL) {
   
		i++;
		p = p->next;
	}
	return (i); //循环结束,p指向尾结点,其序号i为结点个数
}

void DispList(LinkNode *L) //输出线性表
{
   
	LinkNode *p = L->next; //p指向首结点
	while (p != NULL) //p不为NULL,输出p结点的data域
	{
   
		printf("%c ", p->data);
		p = p->next; //p移向下一个结点
	}
	printf("\n");
}

bool GetElem(LinkNode *L, int i, ElemType &e) //求线性表中第i个元素值
{
   
	int j = 0;
	if (i <= 0) return false; //i错误返回假
	LinkNode *p = L; //p指向头结点,j置为0(即头结点的序号为0)
	while (j < i && p != NULL) //找第i个结点p
	{
   
		j++;
		p = p->next;
	}
	if (p == NULL) //不存在第i个数据结点,返回false
		return false;
	else //存在第i个数据结点,返回true
	{
   
		e = p->data;
		return true;
	}
}

int LocateElem(LinkNode *L, ElemType e) //查找第一个值域为e的元素序号
{
   
	int i = 1;
	LinkNode *p = L->next; //p指向首结点,i置为1(即首结点的序号为1)
	while (p != NULL && p->data != e) //查找data值为e的结点,其序号为i
	{
   
		p = p->next;
		i++;
	}
	if (p == NULL) //不存在值为e的结点,返回0
		return (0);
	else //存在值为e的结点,返回其逻辑序号i
		return (i);
}

bool ListInsert(LinkNode *&L, int i, ElemType e) //插入第i个元素
{
   
	int j = 0;
	if (i <= 0) return false; //i错误返回假
	LinkNode *p = L, *s; //p指向头结点,j置为0(即头结点的序号为0)
	while (j < i - 1 && p != NULL) //查找第i-1个结点p
	{
   
		j++;
		p = p->next;
	}
	if (p == NULL) //未找到第i-1个结点,返回false
		return false;
	else //找到第i-1个结点p,插入新结点并返回true
	{
   
		s = (LinkNode *)malloc(sizeof(LinkNode));
		s->data = e; //创建新结点s,其data域置为e
		s->next = p->next; //将结点s插入到结点p之后
		p->next = s;
		return true;
	}
}

bool ListDelete(LinkNode *&L, int i, ElemType &e) //删除第i个元素
{
   
	int j = 0;
	if (i <= 0) return false; //i错误返回假
	LinkNode *p = L, *q; //p指向头结点,j置为0(即头结点的序号为0)
	while (j < i - 1 && p != NULL) //查找第i-1个结点
	{
   
		j++;
		p = p->next;
	}
	if (p == NULL) //未找到第i-1个结点,返回false
		return false;
	else //找到第i-1个结点p
	{
   
		q = p->next; //q指向第i个结点
		if (q == NULL) //若不存在第i个结点,返回false
			return false;
		e = q->data;
		p->next = q->next; //从单链表中删除q结点
		free(q); //释放q结点
		return true; //返回true表示成功删除第i个结点
	}
}
exp2-2.cpp
//文件名:exp2-2.cpp
#include <stdio.h>
#include "linklist.h"

int main() {
   
	LinkNode * h;
	ElemType e;
	printf("单链表的基本运算如下:\n");
	printf("  (1)初始化单链表h\n");
	InitList(h);

	printf("  (2)依次采用尾插法插入a,b,c,d,e元素\n");
	ListInsert(h, 1, 'a');
	ListInsert(h, 2, 'b');
	ListInsert(h, 3, 'c');
	ListInsert(h, 4, 'd');
	ListInsert(h, 5, 'e');

	printf("  (3)输出单链表h:");
	DispList(h);

	printf("  (4)单链表h长度:%d\n", ListLength(h));
	printf("  (5)单链表h为%s\n", (ListEmpty(h) ? "空" : "非空"));
	GetElem(h, 3, e);

	printf("  (6)单链表h的第3个元素:%c\n", e);
	printf("  (7)元素a的位置:%d\n", LocateElem(h, 'a'));
	printf("  (8)在第4个元素位置上插入f元素\n");
	ListInsert(h, 4, 'f');

	printf("  (9)输出单链表h:");
	DispList(h);

	printf("  (10)删除h的第3个元素\n");
	ListDelete(h, 3, e);

	printf("  (11)输出单链表h:");
	DispList(h);

	printf("  (12)释放单链表h\n");
	DestroyList(h);

	return 1;
}

结果

单链表的基本运算如下:
  (1)初始化单链表h
  (2)依次采用尾插法插入a,b,c,d,e元素
  (3)输出单链表h:a b c d e
  (4)单链表h长度:5
  (5)单链表h为非空
  (6)单链表h的第3个元素:c
  (7)元素a的位置:1
  (8)在第4个元素位置上插入f元素
  (9)输出单链表h:a b c f d e
  (10)删除h的第3个元素
  (11)输出单链表h:a b f d e
  (12)释放单链表h
请按任意键继续. . .

实现双链表各种基本运算的算法

放码

dlinklist.h
#ifndef DLINKLIST_H
#define DLINKLIST_H

typedef int ElemType;
typedef struct DNode {
   
	ElemType data;
	struct DNode *prior; //指向前驱结点
	struct DNode *next; //指向后继结点
}DLinkNode; //声明双链表结点类型

void CreateListF(DLinkNode *&L, ElemType a[], int n); //头插法建双链表
void CreateListR(DLinkNode *&L, ElemType a[], int n); //尾插法建双链表
void InitList(DLinkNode *&L); //初始化线性表
void DestroyList(DLinkNode *&L); //销毁线性表
bool ListEmpty(DLinkNode *L); //判线性表是否为空表
int ListLength(DLinkNode *L); //求线性表的长度
void DispList(DLinkNode *L); //输出线性表
bool GetElem(DLinkNode *L, int i, ElemType &e); //求线性表中第i个元素值
int LocateElem(DLinkNode *L, ElemType e); //查找第一个值域为e的元素序号
bool ListInsert(DLinkNode *&L, int i, ElemType e); //插入第i个元素
bool ListDelete(DLinkNode *&L, int i, ElemType &e); //删除第i个元素

#endif
dlinklist.cpp
//双链表运算算法
#include <stdio.h>
#include <malloc.h>
#include "dlinklist.h"

void CreateListF(DLinkNode *&L, ElemType a[], int n) //头插法建双链表
{
   
	DLinkNode *s;
	L = (DLinkNode *)malloc(sizeof(DLinkNode)); //创建头结点
	L->prior = L->next = NULL;
	for (int i = 0; i < n; i++) {
   
		s = (DLinkNode *)malloc(sizeof(DLinkNode)); //创建新结点
		s->data = a[i];
		s->next = L->next; //将结点s插在原开始结点之前,头结点之后
		if (L->next != NULL) L->next->prior = s;
		L->next = s;
		s->prior = L;
	}
}

void CreateListR(DLinkNode *&L, ElemType a[], int n) //尾插法建双链表
{
   
	DLinkNode *s, *r;
	L = (DLinkNode *)malloc(sizeof(DLinkNode)); //创建头结点
	L->prior = L->next = NULL;
	r = L; //r始终指向终端结点,开始时指向头结点
	for (int i = 0; i < n; i++) {
   
		s = (DLinkNode *)malloc(sizeof(DLinkNode)); //创建新结点
		s->data = a[i];
		r->next = s;
		s->prior = r; //将结点s插入结点r之后
		r 
  • 5
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
选题1:(易)实现顺序各种基本运算的算法 参考实验指导书“实验题 1:实现顺序各种基本运算的算法实现”。 选题2:(易)实现单链各种基本运算的算法 参考实验指导书“实验题 2:实现单链各种基本运算的算法实现”。 选题3:(易)编写算法实现二个有序的线性的合并问题(存储结构可选:顺序/单链)。 参考课件“chap002线性.ppt”相关例题。 选题4:(难)运用单向循环链实现约瑟夫环的问题。 参考实验指导书“实验题 4:运用单向循环链实现约瑟夫环的问题”。 选题5:(易)将元素X插入到链中合适的位置。 完成习题集中的算法并编程实现:2.11。参考课件“chap002线性习题讲解.ppt”2.11。 带头结点的单链L,其中有n 个元素非递减有序排列,将元素X插入到链中合适的位置。 提示:先创建链,其中的元素值可由随机函数按阶段生成或键盘输入,先打印初始链数据,然后插入新结点,再打印结果链。 插入前: 插入后: 选题6:(易)删除中所有大于mink且小于maxk的元素。 已知线性中的元素(整数)以值递增有序排列,并以单链作存储结构。试写一高效算法,删除中所有大于mink且小于maxk的元素(若中存在这样的元素),分析你的算法的时间复杂度(注意:mink和maxk是给定的两个参变量,它们的值为任意的整数)。 参考实验指导书“实验题 5:删除有序单链中所有大于 mink 且小于 maxk的元素”。 选题7:(中等)删除单链中多余元素。 完成习题集中的算法并编程实现:2.20。参考课件“chap002线性习题讲解.ppt”2.20。 已知单链中的元素有序,写一算法,删除中所有值相同的多余元素(使操作后线性中的元素值均不相同),同时释放被删结点空间。 选题8:(易)实现单链的就地逆置。 完成习题集中的算法并编程实现:2.22。参考课件“chap002线性习题讲解.ppt”2.22。 试分别以不同的存储结构实现线性的就地逆置算法,即在原的存储空间将线性(a1,a2...,an)逆置为(an,an-1,...,a1)。 选题9:(难)单链拆分。 将带头结点的单链LA中分拆成LB和LC两条单链,LA中的data域为奇数的节点依次进入LB,而为偶数的节点进入LC。 参考课件“chap002线性习题讲解.ppt”第35页例题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值