第二章 线性表

来源:互联网 发布:天津网络大学 编辑:程序博客网 时间:2024/06/01 03:58

一、参数传递-交换值

#include <iostream>using namespace std;//1.传值方式:不改变顺序,修改的是副本的值,实参值不变void swap1(float m,float n){float temp;temp=m;m=n;n=temp;}//2.传地址方式-指针类型做参数,改变顺序,形参变化影响实参void swap2(float *m,float *n){float t;t=*m;*m=*n;*n=t;}//2':不改变顺序void swap3(float *m,float *n){float *t;t=m;m=n;n=t;}//3:传地址方式-引用类型做参数//swap4(a,b)void swap4(float &m,float &n){float temp;temp=m;m=n;n=temp;}void main(){float a,b;cin>>a>>b;swap4(a,b);//swap1(a,b);cout<<a<<endl<<b<<endl;}/*void main(){float a,b,*p1,*p2;cin>>a>>b;p1=&a;p2=&b;swap2(p1,p2);//swap3(p1,p2);cout<<a<<endl<<b<<endl;}*/


//二、用数组作为函数的参数,将数组中n个整数按相反的顺序存放,要求输入和输出在主函数中完成

//偶数个元素-实质是以中轴线,对称交换元素,以数组[1,3,5,7]为例#include <iostream>using namespace std;#define N 4//数组大小void sub(int b[]){int i,j,temp,m;m=N/2;for(i=0;i<m;i++){j=N-1-i;temp=b[i];b[i]=b[j];b[j]=temp;}}void main(){int a[N],i;//输入数组方法2for( i=0;i<N;i++)cin>>a[i];sub(a);for(i=0;i<N;i++)cout<<a[i]<<endl;}

一、顺序表-随机存取-T(n)=O(1)

查找、插入、删除算法的平均时间复杂度为O(n)

顺序表的空间复杂度S(n)=O(1)

(没有占用辅助空间)

//伪代码

#include <iostream>using namespace std;#define MAXSIZE 100//顺序表的存储结构typedef struct{ElemType *elem;//存储空间基地址,ElemType为数据类型,以下为伪代码int length;//当前长度}SqList;//1.初始化顺序表-参数用引用Status InitSqList(SqList &L){L.elem=new ElemType[MAXSIZE];//分配存储空间if(!L.elem)exit(OVERFLOW);L.length=0;return OK;}//1'.初始化顺序表-参数用指针Status InitSqList1(SqList *L){L->elem=new ElemType[MAXSIZE];if(!L->elem)exit(OVERFLOW);L->length=0;return OK;}//2.销毁线性表void DestroyList(SqList &L){if(L.elem)delete[] L.elem;//删除一组对象的存储空间}//3.清空线性表void ClearList(SqList &L){L.length=0;}//4.求线性表的长度int GetLength(SqList L){return L.length;}//5.判断线性表是否为空int IsEmptyList(SqList L){if(L.length==0)return 0;else return 1;}//6.查找-按序号查找//获取L中某个数据元素的内容Status GetElem(SqList L,int i,ElemType &e){if(i<1||i>L.length)//非法值判断与插入的不同return ERROR;e=L.elem[i-1];//第i-1个存储单位存放着第i个数据return OK;}//6'.查找-按值查找//在线性表L中查找值为e的数据元素int LocateElem(SqList L,ElemType e){for(int i=0;i<L.length;i++){if(L.elem[i]==e)return i+1;}return 0;}//7.插入//在线性表L中第i个数据元素之前插入数据元素e Status InsertList(SqList &L,int i,ElemType e){if(i<1||i>L.length+1)return ERROR;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;//表长+1return OK;}//8.删除//将线性表L中第i个数据元素删除Status DeleteList(SqList &L,int i,ElemType e){if(i<1||i>L.length)return ERROR;e=L.elem[i-1];//将要删除的元素保留在e中for(int j=i;j<L.length;j++)L.elem[j-1]=L.elem[j];--L.length;return OK;}<span style="color:#ff0000;font-weight: bold;"></span>


二、链表


顺序存取法

查找O(n),插入和删除为O(1),但插入和删除之前需要查找,则加起来所用On

伪代码:

#include <iostream>using namespace std;//单链表//单链表的存储结构typedef struct LNode{ElemType data;//数据域struct LNode *next;//指针域}LNode,*LinkList;//*LinkList为LNode类型的指针//LNode *p <=> LinkList p//指针变量p:表示结点地址//结点变量*p:表示一个结点//1.初始化Status InitLinkList(LinkList &L){L=new LNode;L->next=NULL;return Ok;}//2.销毁Status DestroyLinkList(LinkList &L){LinkList p;while(L){p=L;L=L->next;delete p;}return Ok;}//3.清空Status ClearLinkList(LinkList &L){LinkList p,q;p=L->next;//p指向第一个节点while(p){q=p->next;delete p;p=q;}L->next=NULL;return Ok;}//4.求表长int LinkListLength(LinkList L){LinkList p;p=L->next;int i=0;while(p){i++;p=p->next;}return i;}//5.判断表是否为空int ListEmpty(LinkList L){//若L为空表,if(L->next)return 1;else return 0;}//6'.查找-按序号查找Status GetElem_L(LinkList L,int i,ElemType &e){LinkList p;p=L->next;int j=1;while(p&&j<i){p=p->next;j++;}if(!p||j>i)return ERROR;e=p->data;return Ok;}//6''在线性表中查找值为e的元素//返回L中值为e的元素地址LNode *LocateElem_L(LinkList L,ElemType e){LinkList p;p=L->next;while(p&&p->data!=e){p=p->next;}return p;}//返回L中值为e的元素位置序号int LocateElem_L(LinkList L,ElemType e){int j=1;LinkList p;p=L->next;while (p&&p->data!=e){p=p->next;j++;}if(p)return j;//若p存在else return 0;}//7.插入//在L中第i个元素之前插入数据元素e,放在a(i-1)和a(i)之间Status ListInsert_L(LinkList &L,int i,ElemType e){LinkList p,s;p=L;//注意此处为=L,而非L->next,为保持位置一致,是寻找当前结点int j=0;while(p&&j<i-1){p=p->next;j++;}if(!p||j>i-1)return ERROR;s =new LNode;s->data=e;s->next=p->next;p->next=s;return Ok;}//8.删除第i个线性表元素Status DeleteLinkList(LinkList &L,int i,ElemType &e){LinkList p,q;int j=0;p=L;while (p->next&&j<i-1)//注意此时判断p->next{p=p->next;j++;}if(!p->next||j>i-1)return ERROR;q=p->next;p->next=q->next;e=q->data;delete q;return Ok;}//9.建立//前插法void  CreateList_F(LinkList &L,int n)//n表示表元素的个数{LinkList p;L=new LNode;L->next=NULL;int i;for(i=n;i>0;i--){p=new LNode;cin>>p->data;p->next=L->next;L->next=p;}}//尾插法void CreateList_B(LinkList &L,int n){L=new LNode;L->next=NULL;LinkList r,p;//需要定义一个来读取Lr=L;for(int i=0;i<n;i++){p=new LNode;cin>>p->data;p->next=NULL;r->next=p;r=p;}}

略 双向链表和循环链表


三、线性表的合并

1.顺序表合并

两个线性表La,Lb,在La中查找该元素,若找不到放在La最后

for(int i=0;i<Lb_Len;i++){GetElem_L(Lb,i,e);if(!LocateElem_L(La,e))ListInsert_L(&La,++La_Len,e);}

T(n)=OLa_Len*Lb_Len

2.有序的线性表合并

有序顺序表:

创建一个新表Lc,依次摘取La,Lb中较小的元素直至一个表为空,将另一个表剩下元素全部放进去

Lc.length=La.length+Lb.length;Lc.elem=new ElemType[Lc.length];pc=Lc.elem;pa_last=La.elem+La.length-1;pb_last=Lb.elem+Lb.length-1;while(pa<=pa_last&&pb<=pb_last){if(*pa<=*pb)*pc++=*pa++;else*pc++=*pb++;}while(pa<=pa_last)//Lb已经到达表尾{*pc++=*pa++;}while(pb<=pb_last){*pc++=*pb++;}

Tn=O(La_len+Lb_len)

S(n)=O(n)


有序链表:

//1.两非递减合并为非递减

void MergeLinkList1(LinkList &La,LinkList &Lb,LinkList &Lc){LinkList pa,pb,pc;pa=La->next;pb=Lb->next;pc=Lc=La;while(pa&&pb){if(pa->data<=pb->data){pc->next=pa;pc=pa;pa=pa->next;}else{pc->next=pb;pc=pb;pb=pb->next;}pc->next=pa?pa:pb;//一表结束,另一表剩下的全部放入Lcdelete Lb;}}

T(n)=O(La_len+Lb_len)

S(n)=O(1)

//2.表中不允许有重复的数

void MergeLinkList2(LinkList &La,LinkList &Lb,LinkList &Lc){LinkList pa,pb,pc,qb;pa=La->next;pb=Lb->next;pc=Lc=La;while(pa&&pb){if(pa->data<pb->data){pc->next=pa;pc=pa;pa=pa->next;}else if(pa->data>pb->data){pc->next=pb;pc=pb;pb=pb->next;}else{pc->next=pa;pc=pa;pa=pa->next;qb=pb->next;delete pb;pb=pb->next;}pc->next=pa?pa:pb;//一表结束,另一表剩下的全部放入Lcdelete Lb;}}

//3.两个非递减为非递增

void union(LinkList &La,LinkList &Lb,LinkList &Lc){LinkList pa,pb,pc,q;pa=La->next;pb=Lb->next;pc=Lc=La;Lc->next=NULL;while(pa||pb){if(!pa){q=pb;pb=pb->next;}else if(!pb){q=pa;pa=pa->next;}else if(pa->data<=pb->data)//哪个小用哪个{q=pa;pa=pa->next;}else {q=pb;pb=pb->next;}//插入q->next=Lc->next;Lc->next=q;}delete Lb;//释放Lb的头指针}

//4.La和Lb递增排列,求出交集放入La中

void Mix(LinkList &La,LinkList &Lb,LinkList &Lc){LinkList pa,pb,pc,q;pa=La->next;pb=Lb->next;Lc=pc=La;while(pa&&pb){if(pa->data==pb->data){pc->next=pa;pc=pa;pa=pa->next;q=pb;pb=pb->next;delete q;}else if(pa->data<pb->data){q=pa;pa=pa->next;delete q;}else{q=pb;pb=pb->next;delete q;}}while(pa)//释放剩下数据的结点空间{q=pa;pa=pa->next;delete q;}while(pb){q=pb;pb=pb->next;delete q;}pc->next=NULL;delete Lb;}

//5.两个递增表La,Lb,求出差集,在La中有,Lb中无,存在La里,并返回该集合的元素个数

int Difference(LinkList &La,LinkList &Lb,LinkList){int n=0;LinkList pa,pb,pc,q;pa=La->next;pb=Lb->next;pc=La;while(pa&&pb){if(pa->data<pb->data){pc->next=pa;pc=pa;pa=pa->next;n++;}else if(pa->data>pb->data){pc->next=pb;pc=pb;pb=pb->next;n++;}else//La和Lb中相同的元素删除{pc->next=pa->next;q=p;p=p->next;delete q;}}//插入剩余段if(pa){while(pa){n++;pa=pa->next;}}else{pc->next=pb;}while(pb){n++;pb=pb->next;}return n;}










0 0
原创粉丝点击