线性表


一.简单介绍   

 线性表是一种典型的数据结构, 线性结构的基本特点是线性表中的数据元素是有序且有限的, 在线性结构中, 有且仅有一个被称为"开始数据元素"和一个"最后数据元素", 除了开始数据元素没有直接前驱, 最后一个数据元素没有直接后继外, 其余的数据元素有且仅有唯一的一个直接前驱和直接后继。对线性表比较详细的介绍。https://www.cnblogs.com/mr-wid/archive/2012/12/07/2807817.html

    整理下来说, 线性表具有如下基本特征:

1.线性结构中必然存在唯一一个"开始数据元素" ;

2.线性结构中必然存在唯一一个"最后数据元素" ;
3.除第一个数据元素外, 其他元素均有唯一一个直接前驱 ;

4.除最后一个数据元素外, 其他元素均有唯一一个直接后继 。

二.基本运算

(一)数组实现

1.线性表的结构体:

typedef int position;
typedef int Elementype;
struct LIST{
	Elementype elements[maxlength];
	int last;
};

2.返回最后一个元素下标:

position End(LIST L){
	return(L.last+1);
}

3.插入操作:

//把x插入到表L中的位置p处 
void Insert(Elementype x,position p,LIST &L){
	position q;
	if(L.last >= maxlength-1)
		cout<<"list is full"<<endl;
	else if((p >L.last+1) ||(p < 1)){
		cout<<"position does not exist"<<endl;
	}
	else{
		for(q = L.last;q >= p;q--){
			L.elements[q+1] = L.elements[q]; 
		}
		L.last = L.last + 1;
		L.elements[p] = x;
	}
}

4.删除操作:

//删除L中位置p中的元素 
void Delete(position p,LIST &L){
	position q;
	if((p >L.last) || (p < 1)){
		cout<<"position does not exist"<<endl;
	}
	else{
		L.last = L.last-1;
		for(q = p;q <= L.last;q++){
			L.elements[q] = L.elements[q+1];
		}
	}
}

5.返回表L中x的位置

//返回表L中x的位置 
position Locate(Elementype x,LIST L){
	position q;
	for(q = 1;q <= L.last;q++){
		if(L.elements[q] == x){
			return q;
		}
	}
	return L.last+1;
}

6.合并两个表L1,L2

void merge(LIST&L,LIST&L1,LIST&L2) {  
	position p=0,p1,p2;  
	position len1=End(L1);  
	position len2=End(L2);  
	
	for(p1=0;p1<End(L1);p1++) 
	{   L.elements[p]=L1.elements[p1];   p++;   }   
	p--; 
	for(p2=0;p2<End(L2);p2++)  
	{   L.elements[p]=L2.elements[p2];   p++;   }  
	p--;
	L.last = p;
}

(二)指针实现

1.线性表的结构体

typedef int Elementype;

struct celltype{
	Elementype element;
	celltype *next;
};

typedef celltype *position;
typedef celltype *LIST;

2.返回线性表L中指向最后一个节点的指针

position End(LIST L){
	position p;
	p = L;
	while(p->next!=NULL){
		p = p->next;
	}
	return p;
}

3.插入操作

void Insert(Elementype x,position p){
	position q;
	q = new celltype;
	q->element = x;
	q->next = p->next;
	p->next = q;
}

4.删除操作

void Delete(position p){
	position q;
	if(p->next != NULL){
		q = p->next;
		p->next = q->next;
		delete q;
	}
}

5.返回L中指向x的指针:

position Locate(Elementype x,LIST L){
	position p;
	p = L;
	while(p->next!=NULL){
		if(p->next->element == x){
			return p;
		}
		else
		p = p->next;
	}
	return p;
}

6.置空表

position MakeNull(LIST &L){
	L = new celltype;
	L->next = NULL;
	return L;
}

7.合并两个表

void merge(LIST &L,LIST &L1,LIST &L2){
	position p,p1,p2;
	for(p1 = L1;p1;p1 = p1->next){
		p = new celltype;
		p->element = p1->element;
		if(L == 0){
			L = p;
			p2 = p;
		}
		else{
			p2->next = p;
			p2 = p;
		}
	}
	p2->next = NULL;
	for(p1 = L2;p1;p1= p1->next){
		p = new celltype;
		p->element = p1->element;
		if(L == 0){
			L = p;
			p2 = p;
		}
		else{
			p2->next = p;
			p2 = p;
		}
	}
	p2->next = NULL;
}
8.复制链表
void Copy(LIST &L,LIST &L1){
	position p,p1,p2;
	for(p1 = L1;p1;p1 = p1->next){
		p = new celltype;
		p->element = p1->element;
		if(L == 0){
			L = p;
			p2 = p;
		}
		else{
			p2->next = p;
			p2 = p;
		}
	}
	p2->next = NULL;
}

三.实例

1.已知一个单向链表,试给出复制该链表的算法。

要求:1、定义线性表的节点的结构以及节点的型和位置的型。
          2、定义线性表的基本操作
          3、在1,2的基础上,完成本题。

         4、在main函数中进行测试:先构建一个线性表,并定义一个空线性表,然后进行复制。

#include<iostream>
using namespace std;
#include<iomanip>
#include<vector>
#include<algorithm> 

typedef int Elementype;

struct celltype{
	Elementype element;
	celltype *next;
};

typedef celltype *position;
typedef celltype *LIST;

position End(LIST L){
	position p;
	p = L;
	while(p->next!=NULL){
		p = p->next;
	}
	return p;
}

void Insert(Elementype x,position p){
	position q;
	q = new celltype;
	q->element = x;
	q->next = p->next;
	p->next = q;
}

void Delete(position p){
	position q;
	if(p->next != NULL){
		q = p->next;
		p->next = q->next;
		delete q;
	}
}

position Locate(Elementype x,LIST L){
	position p;
	p = L;
	while(p->next!=NULL){
		if(p->next->element == x){
			return p;
		}
		else
		p = p->next;
	}
	return p;
}

position MakeNull(LIST &L){
	L = new celltype;
	L->next = NULL;
	return L;
}

void Copy(LIST &L,LIST &L1){
	position p,p1,p2;
	for(p1 = L1;p1;p1 = p1->next){
		p = new celltype;
		p->element = p1->element;
		if(L == 0){
			L = p;
			p2 = p;
		}
		else{
			p2->next = p;
			p2 = p;
		}
	}
	p2->next = NULL;
}

void Read(LIST &L){
	position p1,p2;
	cout<<"输入-1以结束."<<endl;
	while(1){
		p1 = new celltype;
		cin>>p1->element;
		if(p1->element == -1){
			break;
		}
		if(L == 0){
			L = p1;
			p2 = p1;
		}else{
			p2->next = p1;
			p2 = p1;
		}
	}
	p2->next = NULL;
}

void print(LIST &L){
	position p;
	p = L;
	for(;p;p = p->next){
		cout<<p->element<<'\t';
	}
	cout<<endl;
}

int main(){
	LIST L = NULL,L1 = NULL,L2 = NULL;
	Read(L1);
	print(L1);
	Copy(L,L1);
	print(L);
	
	return 0;
}
2.写出从一个带表头的单链表中删除其值等于给定值x的结点的算法函数:
int Delete(LIST &L, int x);如果x在该链表中,则删除对应结点,并返回其在链表中的位置(逻辑位置,第一个结点的逻辑位置为1),否则返回-1。
要求:1、定义线性表的节点的结构以及节点的型和位置的型。
2、定义线性表的基本操作
3、在1,2的基础上,完成本题。

4、在main函数中进行测试:先构建一个线性表,然后调用函数删除值等于给定值的节点。

#include<iostream>
using namespace std;
#include<iomanip>
#include<vector>
#include<algorithm> 

typedef int Elementype;

struct celltype{
	Elementype element;
	celltype *next;
};

typedef celltype *position;
typedef celltype *LIST;

position End(LIST L){
	position p;
	p = L;
	while(p->next!=NULL){
		p = p->next;
	}
	return p;
}

void Insert(Elementype x,position p){
	position q;
	q = new celltype;
	q->element = x;
	q->next = p->next;
	p->next = q;
}

void Delete(position p){
	position q;
	if(p->next != NULL){
		q = p->next;
		p->next = q->next;
		delete q;
	}
}

position Locate(Elementype x,LIST L){
	position p;
	p = L;
	while(p->next!=NULL){
		if(p->next->element == x){
			return p;
		}
		else
		p = p->next;
	}
	return p;
}

position MakeNull(LIST &L){
	L = new celltype;
	L->next = NULL;
	return L;
}

int Delete1(LIST &L,int x){
	position p = L;
	int cnt = 0;

	while(p->next !=NULL){
//		cnt++;
		if(p->next->element == x){
			if(p->next->next!=NULL){
				position q;
				q = p->next;
				p->next = q->next;
				delete q;

			}
			else{
				delete p->next;
				p->next = NULL;

			}
			cnt++;
		}
		else{
			p = p->next;
		}
	}
	return cnt;
}

void Read(LIST &L){
	position p1,p2;
	cout<<"输入-1以结束."<<endl;
	while(1){
		p1 = new celltype;
		cin>>p1->element;
		if(p1->element == -1){
			break;
		}
		if(L == 0){
			L = p1;
			p2 = p1;
		}else{
			p2->next = p1;
			p2 = p1;
		}
	}
	p2->next = NULL;
}

void print(LIST &L){
	position p;
	p = L;
	for(;p;p = p->next){
		cout<<p->element<<'\t';
	}
	cout<<endl;
}

int main(){
	LIST L = NULL,L1 = NULL;
	Read(L);
	print(L);
	Delete1(L,4);
	print(L);
	
	return 0;
}
这一个代码有一丢丢的小问题,就是第一个字母为删除的元素时,不会删除,尝试了几次发现越改越遭,先放一放,之后再改一下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值