顺序表基本操作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 << ' ';
}
}
}
青岛大学王卓老师的数据结构课讲得挺好的,自己写一遍加深对数据结构的理解。