数据结构与算法顺序表C++实现(王卓老师课程)

顺序表基本操作API封装

List_Sq.h

#pragma once
#include<stdlib.h>
#include<iostream>
using namespace std;
//函数结果状态码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define MAXSIZE 100
//Status 是函数的类型,其值是函数结果状态码
typedef int Status;
typedef int ElemType;

typedef struct {
	ElemType *elem;
	int length;
}SqList; //顺序表类型

//线性表L的初始化
Status InitList_Sq(SqList &L) {
	L.elem = new ElemType[MAXSIZE];
	if (!L.elem)exit(OVERFLOW);
	L.length = 0;
	return OK;
}

//销毁线性表L
void DestroyList(SqList &L) {
	if (L.elem)delete L.elem; //释放储存空间
}

//清空线性表L
void ClearList_Sq(SqList &L) {
	L.length = 0; //将线性表长度置为0
}

//判断线性表L是否为空
int IsEmpty_Sq(SqList L) {
	if (L.length == 0)return 1;
	else return 0;
}

//顺序表的取值(根据位置i获取相应位置数据元素的内容)
int GetElem(SqList L, int i, ElemType &e) {
	if (i < 1 || i > L.length)return ERROR;//判断i是否合理
	e = L.elem[i - 1];//第i-1的单元存储着第i个数据
	return OK;
}

//顺序表的查找
int LocateElem(SqList L, ElemType e) {
	//在线性表L中查找值为e的数据元素,返回其序号
	for (int i = 0; i < L.length; i++)
		if (L.elem[i] == e)return i + 1;//查找成功,返回序号
	return 0;//查找失败,返回0
}

//顺序表的插入
Status ListInsert_Sq(SqList &L, int i, ElemType e) {
	if (i<1 || i>L.length + 1)return ERROR; //i值不合法
	if (L.length == MAXSIZE)return ERROR; //当前存储空间已满
	for (int j = L.length - 1; j >= i - 1; j--) //插入位置及之后的元素后移
		L.elem[j + 1] = L.elem[j];
	L.elem[i - 1] = e; //将新元素e放入第i个位置
	L.length++; //表长增1
	return OK;
}

//顺序表的删除
Status ListDelet_Sq(SqList &L, int i) {
	if (i<1 || i>L.length)return ERROR; //i值不合法
	for (int j = i; j <= L.length - 1; j++)
		L.elem[j - 1] = L.elem[j]; //被删除元素之后的元素前移
	L.length--; //表长减1
	return OK;
}

链表基本操作API封装

List_Link.h

#pragma once
#include<stdlib.h>
#include<iostream>
using namespace std;
//函数结果状态码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1

//Status 是函数的类型,其值是函数结果状态码
typedef int Status;
typedef int ElemType;

//单链表
typedef struct Lnode {
	ElemType data;
	struct Lnode *next;
}Lnode,*LinkList;

//双向链表
typedef struct DuLnode {
	ElemType data;
	struct DuLnode *prior,*next;
}DuLnode, *DuLinkList;

//单链表的初始化
Status InitList_L(LinkList &L) {
	L = new Lnode; //或L=(LinkList)malloc(sizeof(Lnode));
	L->next = NULL;
	return OK;
}

//判断链表是否为空
int IsEmpty_Link(LinkList L) { //若L为空表,则返回1,否则返回0
	if (L->next) //非空
		return 0;
	else
		return 1;
}

//销毁单链表L
Status DestroyList_L(LinkList &L) {
	Lnode *p; //或LinkList p;
	while (L) {
		p = L;
		L = L->next;
		delete p;
	}
	return OK;
}

//清空链表L
Status ClearList_L(LinkList &L) { //将L重置为空表
	Lnode *p, *q; //或LinkList p,q;
	p = L->next;
	while (p) { //没到表尾
		q = p->next;
		delete p;
		p = q;
	}
	L->next = NULL; //头节点指针域为空
	return OK;
}

//求单链表L的表长
int ListLength_L(LinkList L) { //返回L中元素的个数
	LinkList p;
	p = L->next;
	int i = 0;
	while (p) {
		i++;
		p = p->next;
	}
	return i;
}

//单链表的取值(取第i个元素)
Status GetElem_L(LinkList L, int i, ElemType &e) {
	LinkList p = L->next; int j = 1; //初始化
	while (p && (j < i)) { //向后扫描,直到p指向第i个元素或p为空
		p = p->next; ++j;
	}
	if (!p || j > i)return ERROR; //第i个元素不存在
	e = p->data; //取第i个元素
	return OK;
}

//按值查找——找到后返回数据元素地址
Lnode *LocateElem_L(LinkList L, ElemType e) {
	//在线性表L中查找值为e的数据元素
	//找到,则返回L中值为e的数据元素的地址,查找失败返回NULL
	LinkList p = L->next;
	while (p && (p->data != e)) {
		p = p->next;
	}
	return p;
}

//按值查找——根据指定数据获取该数据位置序号
//在线性表L中查找值为e的数据元素的位置序号
int LocateElem_p_L(LinkList L, ElemType e) {
	//返回L中值为e的数据元素的位置序号。查找失败返回0
	LinkList p = L->next; int j = 1;
	while (p && (p->data != e)) {
		p = p->next;
		j++;
	}
	if (p)return j;
	else return 0;
}

//在L中第i个元素之前插入数据元素e
Status ListInsert_L(LinkList &L, int i, ElemType e) {
	LinkList p = L; int j = 0;
	while (p && j < (i - 1)) { p = p->next; ++j; } //寻找第i-1个结点,p指向i-1结点
	if (!p || j > i - 1)return ERROR; //i大于表长+1或者小于1,插入位置非法
	LinkList s = new Lnode; s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

//删除——删除第i个结点
Status ListDelete_L(LinkList &L, int i, ElemType &e) {
	LinkList p = L; int j = 0;
	while (p->next && (j < i - 1)) { p = p->next; ++j; } //寻找第i个结点,并令p指向其前驱
	if (!(p->next) || j > i - 1)return ERROR; //删除位置不合理
	LinkList q = p->next;
	p->next = q->next;
	e = q->data;
	delete q;
	return OK;
}

//建立单链表——头插法
void CreateList_H(LinkList &L, int n) { //倒序输入n个元素
	L = new Lnode;
	L->next = NULL;//先建立一个带头节点的单链表
	cout << "请倒序输入要添加的" << n << "个元素,以空格隔开:" << endl;
	for (int i = n; i > 0; --i) {
		LinkList p = new Lnode;//生成新结点p=(Lnode*)malloc(sizeof(Lnode));
		cin >> p->data;//输入元素值scanf(&p->data);
		p->next = L->next; //插入到表头
		L->next = p;
	}
}

//建立单链表——尾插法
void CreateList_R(LinkList &L, int n) { //正序输入n个元素
	L = new Lnode;
	L->next = NULL;
	LinkList r = L; //尾指针r指向头结点
	cout << "请顺序输入要添加的" << n << "个元素,以空格隔开:" << endl;
	for (int i = 0; i < n; ++i) {
		LinkList p = new Lnode;//生成新结点
		cin >> p->data;//输入元素值
		p->next = NULL;
		r->next = p; //插入到表尾
		r = p; //r指向新的尾结点
	}
}


//循环链表——最后一个结点的指针域指向头节点
//带尾指针循环链表的合并
LinkList Connect(LinkList Ta, LinkList Tb) {
	//假设Ta、Tb都是非空的单循环链表
	LinkList p = Ta->next; //p存表头结点
	Ta->next = Tb->next->next; //Tb表头连接Ta表尾
	delete Tb->next; //释放Tb表头结点
	Tb->next = p; //修改指针
	return Tb;
}

//双向链表的取值
DuLinkList GetElemP_DuL(DuLinkList L, int i) {
	DuLinkList p = L->next; int j = 1; //初始化
	while (p && (j < i)) { //向后扫描,直到p指向第i个元素或p为空
		p = p->next; ++j;
	}
	if (!p || j > i)return NULL; //第i个元素不存在
	return p->next;
}

//双向链表的插入
Status ListInsert_DuL(DuLinkList &L, int i, ElemType e) {
	//在带头结点的双向循环链表L中第i个位置之前插入元素e
	DuLinkList p = GetElemP_DuL(L, i);
	if (!p)return ERROR;
	DuLinkList s = new DuLnode;
	s->data = e;
	s->prior = p->prior;
	p->prior->next = s;
	s->next = p;
	p->prior = s;
	return OK;
}

//双向链表的删除
Status ListDelete_DuL(DuLinkList &L, int i, ElemType &e) {
	//删除带头结点的双向循环链表L的第i个元素,并用e返回
	DuLinkList p = GetElemP_DuL(L, i);
	if (!p)return ERROR;
	e = p->data;
	p->prior->next = p->next;
	p->next->prior = p->prior;
	delete p;
	return OK;
}

线性表的合并(顺序表)

/*
问题描述:
	假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合A=A U B
	La=(7,5,3,11) Lb=(2,6,3)  得到:La=(7,5,3,2,6,11)
*/
#include"List_Sq.h"
//顺序表
void Union(SqList &La, SqList Lb) {
	ElemType e;
	for (int i = 1; i <= Lb.length; i++) {
		GetElem(Lb, i, e);
		if (!LocateElem(La, e)) ListInsert_Sq(La, La.length, e);
	}
}

int main(void)
{
	SqList La, Lb;
	InitList_Sq(La);
	InitList_Sq(Lb);
	ListInsert_Sq(La, 1, 7);
	ListInsert_Sq(La, 2, 5);
	ListInsert_Sq(La, 3, 3);
	ListInsert_Sq(La, 4, 11);
	ListInsert_Sq(Lb, 1, 2);
	ListInsert_Sq(Lb, 2, 6);
	ListInsert_Sq(Lb, 3, 3);
	Union(La,Lb);
	for (int j = 0; j < La.length; j++)
		cout << La.elem[j] << ' ';
}

线性表的合并(链表)

/*
问题描述:
	假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合A=A U B
	La=(7,5,3,11) Lb=(2,6,3)  得到:La=(7,5,3,2,6,11)
*/
#include "List_Link.h"
//链表
void Union(LinkList &La, LinkList Lb) {
	int La_len = ListLength_L(La);
	int Lb_len = ListLength_L(Lb);
	ElemType e;
	for (int i = 1; i <= Lb_len; i++) {
		GetElem_L(Lb, i, e);
		if (!LocateElem_L(La, e)) {
			ListInsert_L(La, La_len++, e);
		}
	}
}

int main(void)
{
	LinkList La, Lb;
	ElemType e;
	InitList_L(La);
	InitList_L(Lb);
	CreateList_R(La, 4);
	CreateList_R(Lb, 3);
	Union(La,Lb);
	for (int i = 1; i <= ListLength_L(La); i++) {
		GetElem_L(La, i, e);
		cout << e << ' ';
	}
}

 多项式相加运算(链表)

#include "List_Link.h"

int main()
{
	int n1, n2;
	ElemType e1, e2, e3, e4;
	LinkList la, lb, lc;
	InitList_L(la);
	InitList_L(lb);
	InitList_L(lc);
	cout << "请输入第一个多项式的项数:(包含系数为0的项)" << endl;
	cin >> n1;
	cout << "请输入第二个多项式的项数:(包含系数为0的项)" << endl;
	cin >> n2;
	CreateList_R(la, n1);
	CreateList_R(lb, n2);
	if (n1 > n2) {
		for (int i=1; i <= n2; i++) {
			GetElem_L(la, i, e1);
			GetElem_L(lb, i, e2);
			e3 = e1 + e2;
			ListInsert_L(lc, i, e3);
		}
		for (int j = n2+1; j <= n1; j++) {
					GetElem_L(la, j, e1);
					ListInsert_L(lc, j, e1);
		}
		cout << "相加后多项式的系数:" << endl;
		for (int k = 1; k <= n1; k++) {
			GetElem_L(lc, k, e4);
			cout << e4 << ' ';
		}
	}
	else if (n1 < n2) {
		for (int i=1; i <= n1; i++) {
			GetElem_L(la, i, e1);
			GetElem_L(lb, i, e2);
			e3 = e1 + e2;
			ListInsert_L(lc, i, e3);
		}
		for (int j = n1+1; j <= n2; j++) {
			GetElem_L(lb,j, e2);
			ListInsert_L(lc,j, e2);
		}
		cout << "相加后多项式的系数:" << endl;
		for (int k = 1; k <= n2; k++) {
			GetElem_L(lc, k, e4);
			cout << e4 << ' ';
		}
	}
	else {
		int i = 1;
		for (i; i <= n2; i++) {
			GetElem_L(la, i, e1);
			GetElem_L(lb, i, e2);
			e3 = e1 + e2;
			ListInsert_L(lc, i, e3);
		}
		cout << "相加后多项式的系数:" << endl;
		for (int k = 1; k <= n1; k++) {
			GetElem_L(lc, k, e4);
			cout << e4 << ' ';
		}
	}
}

         青岛大学王卓老师的数据结构课讲得挺好的,自己写一遍加深对数据结构的理解。

https://www.bilibili.com/video/BV1nJ411V7bd/?spm_id_from=333.337.search-card.all.click&vd_source=26707a904a0546953257b4a84aaba7ad

 

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是修改后的代码,注释中标注了修改的地方和问题: ```c #include<stdio.h> #include<stdlib.h> // 修改:头文件 <malloc.h> 应改为 <stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -2 typedef int Status; typedef int ElemType; typedef struct node { ElemType data; struct node* next; // 修改:指针变量名应为 next,而不是 node } Node; // 修改:结构体名应为 Node,而不是 node typedef Node* LinkList; // 修改:LinkList 应为 Node* 类型 // 修改:InitList 应该返回 Status 类型 Status InitList(LinkList* l) { *l = (LinkList)malloc(sizeof(Node)); (*l)->next = NULL; // 修改:NULL 应该用大写字母 return OK; } void CreateList(LinkList L, int n) { // 修改:函数名应该为 CreateList Node* s; char c; int flag = 1; while (flag) { c = getchar(); if (c != 's') { s = (Node*)malloc(sizeof(Node)); s->data = c; s->next = L->next; L->next = s; } else flag = 0; } } Node* GetNode(LinkList L, int i) { // 修改:函数名应该为 GetNode int j = 0; Node* p = L->next; // 修改:初始化 p 时应该为 L->next,而不是 L if (i <= 0) return NULL; // 修改:返回值为 NULL,而不是 null while (p && j < i - 1) { // 修改:应该为 i - 1 p = p->next; j++; } return p; } int LocateElem(LinkList L, ElemType e) { // 修改:函数名应该为 LocateElem int i = 1; Node* p = L->next; while (p) { if (p->data == e) return i; p = p->next; i++; } return 0; // 修改:查找失败时返回 0,而不是 NULL } int main(void) { int n, e; // 修改:需要定义变量 e LinkList L; printf("输入要创建的单链的元素个数\n"); scanf("%d", &n); InitList(&L); printf("请输入各个元素 \n"); CreateList(L, n); printf("创建的单链成功\n"); printf("第二个元素值:%c\n", L->next->next->data); // 修改:应该用 %c 输出字符型数据 printf("请输入要查找的数据:\n"); scanf("%d", &e); if (LocateElem(L, e) == 0) printf("查找失败\n"); // 修改:查找失败时输出“查找失败” else printf("数据所在位置为%d\n", LocateElem(L, e)); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值