基于c/c++的数据结构-线性表

线性表

含义及特点

1.线性表的含义:是由n(n>=0)个类型相同的数据元素组成的有限序列。数据元素之间有一对一的关系。
2.线性表的特点:同一性,有穷性,有序性。

线性表的顺序存储(随机存取)

1.顺序存储结构

#define MAXSIZE 100
struct SeqList
{
ElemType elem[MAXSIZE];
int last;
};

  • [1]ElemType 可以具体为int,float,char或一种struct结构类型
  • [2]区分元素序号和元素在数组中下标的对应关系,元素在数组中下标为0,元素起始序号为1.
  • [3]类型是模板,变量是真正的存储空间

2.顺序存储结构上的基本运算
(1)插入:在顺序表l中第i个数据元素前插入一个元素e,i的合法取值为1<=i<=l.last+2.

void InsertSeqlist(SeqList l,int i,ElemType e)
{
if(i<1 || i>l->last+2) /先判断插入位置是否合法/
{
return;
}
if(l->last>=MAXSIZE-1) /
判断最后一个元素下标是否超过表的限制*/
{
return;
}
for(int k=l->last;k>=i-1;k–)
{
l->elem[k+1]=l->elem[k];
}
l->elem[i-1]=e;
l->last++;
}

  • [1]在长度为n的表中插入一元素所需移动元素的平均次数是n/2.

(2)删除:在顺序表中删除第i个数据元素,i的合法取值为1<=i<=l.last+1.

void DeleteSeqlist(SeqList *l,int i,ElemType *e)
{
if( i<1 || i>l->last+1) /判断删除位置是否合法/
{
return;
}
*e=l->elem[i-1];
for(int k=i;i<=l->last;k++)
{
l->elem[k-1]=l->elem[k];
}
l->last–;
}

  • [1] 在长度为n的表中删除一元素所需移动元素的平均次数是(n-1)/2.

3.例题:(1)合并两有序线性表 (2)左奇右偶 ,左正右负(3)求并集交集 (4)约瑟夫环
eg:利用顺序表调整其为左右两部分,左边的为奇数,右边的为偶数

void AdjustSeqlist(SeqList *L)
{
int i=0,j=L->last;
int t;
while(i<j)
{
while(L->elem[i]%2!=0)
i++;
while(L->elem[j]%2==0)
j–;
if(i<j)
{
t=L->elem[i];
L->elem[i]=L->elem[j];
L->elem[j]=t;
}
}
}

线性表的链式存储

1.单链表的存储结构

typedef struct Node
{
ElemType data;
struct Node *next;
}*LinkList;

2.单链表上的基本运算
(1)初始化单链表

void InitList(LinkList *L)
{
//*L=(LinkList)malloc(sizeof(Node)); c语言中
*L=new Node;
(*L)->next=NULL;
}

(2)头插法建立单链表

void CreatFromHead(LinkList L)
{
Node *s;
char c; //这里将ElemType具体为char类型
int flag=1;
while(flag)
{
cin>>c;
if(c!=’$’)
{
//s=(Node *)malloc(sizeof(Node));
s=new Node;
s->data=c;
s->next=NULL;
s->next=L->next;
L->next=s;
}
else
flag=0;
}
}

(3)尾插法建立单链表

void CreatFromTail(LinkList L)
{
Node *s,*r;
char c; //这里将ElemType具体为char类型
int flag=1;
r=L;
while(flag)
{
cin>>c;
if(c!=’$’)
{
// s=(Node *)malloc(sizeof(Node));
s=new Node;
s->data=c;
r->next=s;
r=s;
}
else
{
flag=0;
r->next=NULL;
}
}
}

(4)插入:第i个位置前插入一个新元素e,则查找第i-1个结点,将e插入到第i和第i-1个结点之间

void InsertList(LinkList L,int i,ElemType e)
{
Node *pre,s;
pre=L;
int k=0;
while(pre!=NULL && k<i-1)
{
pre=pre->next;
k+=1;
}
if(pre!=NULL)
{
return;//插入位置不合理
}
s=new Node;
// s=(Node
)malloc(sizeof(Node));
s->data=e;
s->next=pre->next;
pre->next=s;
}

(5)删除:删除第i个元素e,则查找第i-1个结点,然后删除第i个结点并释放结点空间

void DeleteList(LinkList L,int i,ElemType *e)
{
Node *pre,*r;
pre=L;
int k=0;
while(pre->next!=NULL && k<i-1)
{
pre=pre->next;
k+=1;
}
if(pre->next==NULL)
{
return;
}
r=pre->next;
pre->next=r->next;
*e=r->data;
free®;
}

3.例题:(1)合并(2)就地逆置(3)二进制数加一运算(4)以某值划分结点
eg:链表的合并
【问题描述】
两个非降序链表的并集,例如将链表1->2->3 和 2->3->5 并为 1->2->3->5,只能输出结果,不能修改两个链表的数据。
【输入形式】
第一行首先是数据的个数,然后是第一个链表的各结点值,以空格分隔。
第二行首先也是数据的个数,然后是第二个链表的各结点值,以空格分隔。
【输出形式】
合并好的链表,以非降序排列,值与值之间以空格分隔。
【样例输入】
4 4 7 10 34
7 1 4 6 29 34 34 52
【样例输出】
1 4 6 7 10 29 34 52

#include <iostream //加一个‘’>‘’
using namespace std;
typedef struct Node
{
int data;
struct Node *next;
}*LinkList;
InitList(LinkList *L)
{
*L=new Node;
(*L)->next=NULL;
}
void CreatFromTail(LinkList L,int len)
{
int data_,i;
Node *s,*r;
r=L;
for(i=1;i<=len;i++)
{
s=new Node;
cin>>data_;
s->data=data_;
r->next=s;
r=s;
}
r->next=NULL;
}
void ShowList(LinkList L)
{
Node *p=L;
while(p->next)
{
p=p->next;
cout<data<<" ";
}
}
LinkList ConnectList(LinkList La,LinkList Lb)
{
LinkList Lc;
Node *pa,*pb,*pc,*r;
pa=La->next; //pa指向La的第一个结点
pb=Lb->next;
Lc=La;
Lc->next=NULL;
r=Lc; //r始终指向Lc的表尾,初值指向Lc
while(pa!=NULL &&pb!=NULL)
{
if(pa->data<=pb->data)
{
r->next=pa;
r=pa;
pa=pa->next;
}
else
{
r->next=pb;
r=pb;
pb=pb->next;
}
}
if(pa)
{
r->next=pa;
}
else
r->next=pb;
pc=Lc->next;
while(pc->next!=NULL)
{
if(pc->data!=pc->next->data)
{
pc=pc->next;
}
else
{
pc->next=pc->next->next;
}
}
return Lc;
}
int main()
{
int lena,lenb;
LinkList La,Lb,Lc;
InitList(&La);
cin>>lena;
CreatFromTail(La,lena);
InitList(&Lb);
cin>>lenb;
CreatFromTail(Lb,lenb);
Lc=ConnectList(La,Lb);
ShowList(Lc);
return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值