顺序表
//SqList.h文件夹
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int SLdataType;
typedef struct SeList {
SLdataType *a;
int size;
int capacity;
}SL;
void InitList(SL *ps);// 初始化一个顺序表
/*
在对一个初始化好后的顺序表进行操作之前,要先考虑扩容
*/
void SLCheckCapacity(SL *ps);
/*
增加一个元素
*/
void ListInsert(SL *ps,SLdataType e,int pos);
/*
删除一个元素
*/
void ListDelete(SL *ps,int pos);
/*
查找一个元素
*/
void LocalList(SL *ps,SLdataType e);
void SLprint(SL *ps);
/*
SqList.cpp文件夹
*/
#include"SqList.h"
void InitList(SL *ps){
assert(ps);
ps->a = NULL;
ps->size = 0;
ps->capacity = 0;
}
void SLCheckCapacity(SL *ps) {
assert(ps);
if (ps->size == ps->capacity) {
int newCapacity =ps->capacity == 0 ? 4 : ps->capacity * 2;
SLdataType* temp =(SLdataType*)realloc(ps->a,newCapacity*sizeof(SLdataType));
if (temp == NULL) {
perror("realloc fail");
exit(-1);
}
ps->a = temp;
ps->capacity = newCapacity;
}
}
void ListInsert(SL *ps,SLdataType e,int pos) {
assert(ps);
if ((pos<0)||(pos>ps->size)) {
exit(-1);
}
SLCheckCapacity(ps);
int end = ps->size - 1;
for (; end >= pos;end--) {
ps->a[end+1] = ps->a[end];
}
ps->a[pos]=e;
ps->size++;
}
void ListDelete(SL *ps,int pos) {
if ((pos<0)||(pos>ps->size-1)||(ps->size==0)) {
exit(-1);
}
for (int i = pos; i < ps->size-1;i++) {
ps->a[i] = ps->a[i+1];
}
ps->size--;
}
void LocalList(SL *ps,SLdataType e) {
if (ps->size==0) {
exit(-1);
}
for (int i = 0; i < ps->size;i++) {
if (ps->a[i]==e) {
printf("找到此元素\n");
exit(-1);
}
}
printf("未找到此元素\n");
exit(-1);
}
void SLprint(SL *ps) {
assert(ps);
for (int i = 0; i < ps->size;i++) {
printf("%d ",ps->a[i]);
}
printf("\n");
}
/*
测试文件夹:test.cpp
*/
#include"SqList.h"
void TestListInsert() {
SL s1;
InitList(&s1);
ListInsert(&s1,1,0);
ListInsert(&s1, 2, 1);
SLprint(&s1);
}
void TestListDelete() {
SL s1;
InitList(&s1);
ListInsert(&s1, 1, 0);
ListInsert(&s1, 2, 1);
ListInsert(&s1, 3, 2);
ListInsert(&s1, 4, 3);
SLprint(&s1);
ListDelete(&s1,1);
SLprint(&s1);
}
void TestLocalList() {
SL s1;
InitList(&s1);
ListInsert(&s1, 1, 0);
ListInsert(&s1, 2, 1);
ListInsert(&s1, 3, 2);
ListInsert(&s1, 4, 3);
LocalList(&s1,3);
}
int main() {
TestListDelete();
return 0;
}
单链表
SList.h
/*
简介:对单链表完成简单的初始化,查找,增删操作
*/
#pragma once
#include<stdio.h>
#include "stdlib.h"
#include<iostream>
typedef int Status;
#define OK 1;
#define ERROR 0;
using namespace std;
typedef int LDataType;
typedef struct LNode {
int data;
struct LNode* next;
}LNode,*LinkList;
/*
初始化一个链表
*/
Status NewLNode(LinkList& L);
/*
按位置查找
*/
int GetElem(LinkList L,int i);
/*
按值查找
*/
void LocalElem(LinkList L,LDataType e);
/*
在指定的位置插入一个数
*/
void InsertList(LinkList L,int i,LDataType e);
/*
删除指定位置的元素
*/
void DeleteList(LinkList &L,int i);
/*
求单链表的长度
*/
int lengthList(LinkList L);
SList.cpp
#include "SList.h"
/*
这里形参使用了一级指针的引用,或者二级指针,初始化头指针,即修改头指针的值,
所以按照传参的规则,需要传递指针的地址,
而在增减元素时,不需要修改头指针,所以不需要传递一级指针的地址,但也可以传递二级指针进行增删操作
*/
Status NewLNode(LinkList& L) {
L = (LinkList)malloc(sizeof(LNode)); /* 产生头结点,并使L指向此头结点 */
if (!L) /* 存储分配失败 */
return ERROR;
L->next = NULL; /* 指针域为空 */
return OK;
}
int GetElem(LinkList L,int i) {
LNode *p=L;
int j = 0;
while (p && j<i) {
p = p->next;
j++;
}
if (!p || j > i) {
cout << "此位置无元素";
return 0;
}
else
cout << "此位置有元素,为:"<<p->data;
return p->data;
}
void LocalElem(LinkList L,LDataType e) {
LinkList p =L;
while(p){
if(p->data == e)
cout<<"找到此元素\n";
exit(-1);
else{
p=p->next;
}
}
cout<<"未找到此元素";
}
void InsertList(LinkList L, int i, LDataType e) {
LinkList p = L;
int j = 0;
while (p && j < i - 1) {
p = p->next;
j++;
}
if (!p || j > i - 1) {
cout << "位置不合法";
}
else {
LNode* s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
}
}
/*
删除第i+1位置的元素
*/
void DeteleList(LinkList L,int i){
LNode* p=L;
int j=0;
while(p->next &&j<i-1){
p=p->next;
j++;
}
if(!(p->next)||j>i-1)
exit(-1);
p->next=p->next->next;
}
int LengthList(LinkList L){
LNode* P =L;
int length =0;
while(p){
length++;
p=p->next;
}
return length;
}
test.cpp
#include"SList.h"
void ListPrint(LinkList L) {
LNode* p = L->next;
if()
while (p) {
cout << p->data<<"\n";
p = p->next;
}
}
void main() {
LinkList L;
NewLNode(L);
InsertList(L,1,1);
InsertList(L, 2, 2);
InsertList(L, 3, 3);
GetElem(L,0);
}
两个线性表的合并
void unio(LinkList A,LinkList B){
LNode* p_A =A;
LNode* p_B =B;
while(p_B->next){
TDataType Insert_elem =GetElem(p_B,1);
bool b =localelem(p_A,Insert_elem);
int length =LengthList(p_A);
if(!b){
InsertList(p_A,length,Insert_elem);
length++;
}
DeteleList(p_B,1);
}
}
有序链表的基本操作
一、使用顺序表
/*
将La 和Lb中的数据合并为一个顺序表,并且有序放入Lc中,
*/
void MergeList(SL La,SL Lb,SL *Lc){
SLdataType *pa =La.a;
SLdataType *pa_last =La.a+La.size-1;
SLdataType *pb =Lb.b;
SLdataType *pb_last =Lb.a+Lb.size-1;
int length =La.size+Lb.size;
Lc.a =new SLdataType[length];
Lc.size =length;
SLdataType* pc =Lc.a;
while(pa<=pa_last&&pb<=pb_last){
if(*pa<=*pb){
*pc++=*pa++;
}else{
*pc++ =*pb++;
}
}
while(pa<=pa_last)
{
*pc++=*pa++;
}
while (pb <= pb_last) {
*pc++ = *pb++;
}
}
二 、使用链表
/*
将有序链表A和B合并为一个有序的链表,思路:
设立一个指针C指向A的头结点,然后将链表A和B摘下来连接到C的后面,
这样对于A链表,在指针pa前面的结点发生了变化(变为合并后链表),但pa后面的没有发生变化,依然为A链表。
*/
void MergeList(LinkList A,LinkList B,LinkList &C) {
LNode* pa = A->next;
LNode* pb = B->next;
C = A;
LNode* pc = C;
while (pa&&pb) {
if (pa->data>=pb->data) {
pc->next = pb;
pc = pb;
pb = pb->next;
}
else {
pc->next = pa;
pc = pa;
pa = pa->next;
}
}
while (pa) {
pc->next = pa;
pc = pa;
pa = pa->next;
}
while (pb) {
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
/*
将两个递增的有序链表合并为一个有序的链表,并且不能有重复的元素
LA: 有序表一
LB: 有序表二
LC: 将合并的结果存放在C中
*/
void MergeList2(LinkList LA,LinkList LB,LinkList& LC) {
LNode* pa = LA->next;
LNode* pb = LB->next;
LC = LA;
LNode* pc = LC;
while (pa&&pb) {
if (pa->data<pb->data)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
else if (pa->data==pb->data)
{
pc->next = pa;
pc = pa;
pa = pa->next;
pb = pb->next;
}
else
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
while (pa)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}while (pb)
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
/*
将两个非递增的有序链表合并为一个非递减的有序表,允许重复
*/
void MergeList3(LinkList LA, LinkList LB, LinkList& LC) {
LNode* pa = LA->next;
LNode* pb = LB->next;
LC = LA;
LNode* pc = LC;
LC->next = NULL;
while (pa && pb) {
if (pa->data <= pb->data)
{
LNode* px1 = pa->next;
pa->next=LC->next;
LC->next=pa;
pa = px1;
}
else
{
LNode* px2 = pb->next;
pb->next = LC->next;
LC->next = pb;
pb = px2;
}
}
LNode* p = pa ? pa : pb;
while (p)
{
LNode* px3 = p->next;
p->next = LC->next;
LC->next = p;
p= px3;
}
}
/*
两个递增的有序表A,B求出交集并放入C中,
过程: 若A>B,把B向后移动
若A<B,把A向后移动
若A=B,把A插入C中, A,B向后移动
*/
void MergeList4(LinkList A,LinkList B,LinkList& C){
LNode* pa =A->next;
LNode* pb =B->next;
LC =LA;
LNode* pc =LC;
while(pa&&pb){
if(pa->data>pb->data){
pb =pb->next;
}else if(pa->data < pb->data){
pa=pa->next;
}else{
pc->next =pa;
pc =pa;
pb=pb->next;
pa=pa->next;
}
}
}
一元多项式
<!--Polyn.h-->
#pragma once
#include<iostream>
using namespace std;
/*
用结构体表示多项式,
coef:项系数,
exp :项指数,
next: 下一个项
*/
typedef struct PNode
{
float coef;
int exp;
struct PNode* next;
}PNode,*LinkPNode;
/*
多项式的初始化
*/
void InitPolyn(LinkPNode& L, int n);
/*
输出多项式
*/
void PrintPolyn(LinkPNode L);
/*
多项数相加
LA:多项式LA
LB:多项式LB
LC:将LA和LB相加的结果存于LC中
*/
void addPolyn(LinkPNode LA, LinkPNode LB, LinkPNode& LC);
Polyn.cpp
#include"Polyn.h"
/*
多项式的初始化
L:指向链表的头指针
n:要插入的项数
在插入一个项之前,要先找到该项插入的位置,
*/
void InitPolyn(LinkPNode& L, int n) {
L = new PNode;
L->next = NULL;
cout << "系数 指数\n";
for (int i = 0; i < n; i++)
{
PNode* s = new PNode;
cin >> s->coef>>s->exp;
cout << "\n";
PNode* per = L;
PNode* p = per->next;
/*
这个while的作用是用来找到s要插入的位置:per和p之间
*/
while (p && p->exp < s->exp) {
per = p;
p = p->next;
}
s->next = p;
per->next = s;
}
}
/*
多项式的输出
L:指向多项式的头指针
*/
void PrintPolyn(LinkPNode L) {
PNode* p = L->next;
while (p) {
if (p->exp ==0)
{
cout << p->coef;
}
else {
cout <<"+" << p->coef << "*X^" << p->exp;
}
p = p->next;
}
}
/*
多项数相加
LA:多项式LA
LB:多项式LB
LC:将LA和LB相加的结果存于LC中
*/
void addPolyn(LinkPNode LA, LinkPNode LB, LinkPNode& LC) {
PNode* pa = LA->next;
PNode* pb = LB->next;
LC = LA;
PNode* pc = LC;
while (pa && pb) {
if (pa->exp == pb->exp)
{
float sum = pa->coef + pb->coef;
if (sum != 0) {
pa->coef = sum;
pc->next = pa;
pc = pa;
pa = pa->next;
pb = pb->next;
}
else {
PNode* r = pa;
pa = pa->next;
delete r;
r = pb;
pb = pb->next;
delete r;
}
}
else if (pa->exp < pb->exp) {
pc->next = pa;
pc = pa;
pa = pa->next;
}
else {
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
while (pa)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
while (pb) {
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
test.cpp
#include"Polyn.h"
void main()
{
LinkPNode L1,L2,L3;
InitPolyn(L1,3);
InitPolyn(L2,4);
addPolyn(L1,L2,L3);
PrintPolyn(L3);
}
小总结
对于链表的操作,第一步基本是先用指针指向它,然后再进行对应的操作,要掌握一些基本的操作,当对两个线性表进行操作时,基本是通过两个指针各自指向一个链表,然后进行对比.