线性表1
一、写一个算法合并两个已排序的线性表,合并为一个递增序列,新序列中的元素各不相同。
(用两种方法:数组表示的线性表(顺序表)和指针表示的线性表(链表))
要求:1、定义线性表节点的结构,并定义节点的型和位置的型。
2、定义线性表的基本操作
3、在1,2的基础上,完成本题。
4、在函数中进行测试:先构建两个有序的线性表,然后合并这两个线性表。
二、已知一个单向链表,试给出复制该链表的算法。
要求:1、定义线性表的节点的结构以及节点的型和位置的型。
2、定义线性表的基本操作
3、在1,2的基础上,完成本题。
4、在main函数中进行测试:先构建一个线性表,并定义一个空线性表,然后进行复制。
三、写出从一个带表头的单链表中删除其值等于给定值x的结点的算法函数:
int delete(LIST &L, int x);如果x在该链表中,则删除对应结点
要求:1、定义线性表的节点的结构以及节点的型和位置的型,并返回其在链表中的位置(逻辑位置,第一个结
点的逻辑位置为1 ),否则返回-1。
2、定义线性表的基本操作
3、在1,2的基础上,完成本题。
4、在main函数中进行测试:先构建一个线性表,然后调用函数删除值等于给定值的节点。
//数组表示的线性表(顺序表),从来没考过
#include <iostream>
using namespace std;
#define maxlength 100
typedef int Elementtype;
typedef int position;
struct LIST
{
Elementtype elements[maxlength];
int last;//表中最后一个元素在表中的位置
};
//表中第i个元素存放在数组中下标为i的的单元内(1<=i<=last)
position END(LIST L)//对于具有n个元素的线性表L,返回位置n之后的这个位置
{
return (L.last+1);
}
void Insert(Elementtype x,position p,LIST &L)//在线性表的p位置插入元素x
{
position q;
if(L.last>=maxlength-1)
cout<<"表满!\n";
else if(p>L.last+1||p<1)
cout<<"指定位置不存在!\n";
else
{
for(q=L.last;q>=p;q--)
L.elements[q+1]=L.elements[q];
L.last=L.last+1;
L.elements[p]=x;
}
}
position Locate(Elementtype x,LIST L)//返回线性表中 值为x的元素 的位置
{
position p;
for(p=1;p<=L.last;p++)
if(L.elements[p]==x){
cout<<L.elements[p];
}
return p;
return (L.last+1);
}
void Delete(position p,LIST &L) //删除线性表中 位置为p 的元素
{
position q;
if(p>L.last||p<1) //第一个元素在数组下标为1的位置
cout<<"该位置不存在!\n";
else{
L.last=L.last-1;
for(q=p;q<=L.last;q++)
L.elements[q]=L.elements[q+1];
}
}
//主要函数,合并两张表到一张新表中
void merge(LIST &L,LIST &L1,LIST &L2)
{
position p=1,p1,p2;
position len1=END(L1);
position len2=END(L2);
L.last=len1+len2-2;
for(p1=1;p1<END(L1);p1++)
{
L.elements[p]=L1.elements[p1];
p++;
}
for(p2=1;p2<END(L2);p2++)
{
L.elements[p]=L2.elements[p2];
p++;
}
}
void read(LIST &L)//对一个新创建的线性表读入数据
{
cout<<endl;
cout<<"请输入线性表长度:";
cin >>L.last;
for(int i =1;i<=L.last;i++)
{
cin>>L.elements[i];
}
cout<<endl;
}
void write(LIST L)//输出线性表的所有数据
{
for(int i =1;i<=L.last;i++)
{
cout<<L.elements[i]<<'\t';
}
cout<<endl;
}
int main()
{
LIST L1,L2,L;
read(L1);
write(L1);
//Delete(3,L1);//删的是数组下标为3的元素
//write(L1);
//write(L1);
Locate(1,L1);
//read(L2);
//write(L2);
//merge(L,L1,L2);
//write(L);//为什么合并之后会多出来一个数据?
}
指针表示的线性表(链表)
#include<iostream>
using namespace std;
typedef int elementtype;
struct celltype{//结点的指针域中的指针指向下一个结点,被指向的结点中元素的位置定义为指向它前导结点的指针
elementtype element;
celltype *next;
};
typedef celltype *LIST;
typedef celltype *position;
position END (LIST L)//这个L实质上也是一个结点,头结点 ,返回指向L中最后一个结点的指针
{
position q;
q = L;
while ( q->next!=NULL)
q = q->next;
//cout<<"最后一个元素为"<<q->element<<endl;
return q;
}
void INSERT (elementtype x,position &p)//定义这个p的类型为结点类型,利用这个结点中的指针域表示位置(表示的是下一个结点中元素的位置)
{
position temp;
temp = new celltype;
temp->element = x;
temp->next = p->next;
p->next = temp;
}
position LOCATE(elementtype x , LIST L)//返回线性表L中元素x的位置 ,a元素的位置规定为a所在结点的直接前导结点的指针
{
position p ;
p = L;
while ( p->next!=NULL)
if(p->next->element == x){
//cout<<x<<"前面的元素为"<<p->element;
return p;}
else
p = p->next;
return p ;
}
void DELETE(position &p)
{
position q;
if(p->next!=NULL)
{
q = p->next;
p->next = q->next;
delete q;
}
}
position MakeNull(LIST &L)
{
L = new celltype;
L->next = NULL;
return L;
}
elementtype Retrieve(position p)
{
cout<<"该位置的元素为(某元素的位置为指向它的前导结点的指针)"<<p->next->element<<endl;
return (p->next->element);
}
void Read(LIST &L)//带有头结点的线性表
{
L = new celltype;
L->next = NULL;
position p1,p2;
p2 = L;//p2指向表的尾结点
cout<<"请输入数据以-1结束"<<endl;
for(;;)
{
p1=new celltype;
cin>>p1->element;
if(p1->element==-1)
break;
p2->next=p1;
p2=p1;
}
p2->next=NULL;
}
void write(LIST L)
{
position p;
p=L->next;
int i = 0;
for(;p;p=p->next)
{
cout<<"第"<<++i<<"个元素为"<<p->element<<endl;
}
cout<<endl;
}
int main()
{
LIST L=NULL,L1=NULL,L2=NULL;
Read(L1);
write(L1);
//copy(L,L1);
//write(L);
DELETE(L1,2);//删除值为2的结点
write(L1);
//MakeNull(L1);
//write(L1);
//Retrieve(L1);// 输出L1的头结点之后的那个结点的元素
//DELETE(L1);//删除表头结点后的那个元素
//write(L1);
//LOCATE(3,L1);
//INSERT(3,L1->next);//在L1的头结点之后的之后插入元素3
//write(L1);
//END(L1);
//Read(L2);
//write(L2);
//merge(L,L1,L2);
//write(L);
//LOCATE(1,L);
}
合并两个已排序的线性表,合并为一个递增序列,新序列中的元素各不相同
void merge2(LIST&L,LIST L1,LIST L2)
{
position p;
position p1=L1->next; //指向L1的动态结点
position p2=L2->next; //指向L2的动态结点
position p3; //指向L的表尾
L = new celltype;
L->next = NULL;
p3 = L;
while(p1!=NULL && p2!=NULL){
if(p1->element<p2->element){
p = new celltype;
p->element = p1->element;
p3->next =p;
p3=p;
p1=p1->next;
}
else if(p1->element>p2->element){
p = new celltype;
p->element = p2->element;
p3->next =p;
p3=p;
p2=p2->next;
}
else{
p = new celltype;
p->element = p1->element;
p3->next =p;
p3=p;
p1=p1->next;
p2=p2->next;
}
}
while(p1!=NULL){
p = new celltype;
p->element = p1->element;
p3->next =p;
p3=p;
p1=p1->next;
}
while(p2!=NULL){
p = new celltype;
p->element = p2->element;
p3->next =p;
p3=p;
p2=p2->next;
}
p3->next=NULL;
}
已知一个单向链表,复制该链表
void copy(LIST &L,LIST L1)
{
position p;
position p1; //动态结点
position p2; //p2指向新表的尾结点
L = new celltype;
L->next = NULL;
p2 = L;
for(p1 = L1->next;p1;p1 = p1->next)
{
p = new celltype;
p->element = p1->element;
p2->next =p;
p2=p;
}
p2->next = NULL;
}
从一个带表头的单链表中删除其值等于给定值x的结点
int DELETE(LIST &L,int x) // 从一个带表头的单链表中删除其值等于给定值x的结点的算法,可以了试试
{
position p = L->next;
int count =1;
if(p->element ==x)
{
return count;
L->next=p->next;
}
while(p->next!=NULL)
{
count++;
if(p->next->element ==x)
{
if(p->next->next!=NULL)
{
position q;
q=p->next;
p->next=q->next;
delete q;
return count;
}
else
{
delete p->next;
p->next=NULL;
return count;
}
}
else
{
p=p->next;
}
}
return -1;
}