数据结构——线性表

顺序表

//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);
}

小总结

对于链表的操作,第一步基本是先用指针指向它,然后再进行对应的操作,要掌握一些基本的操作,当对两个线性表进行操作时,基本是通过两个指针各自指向一个链表,然后进行对比.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值