数据结构—线性表顺序存储与链式存储结构操作

1.线性表顺序存储结构

1.顺序存储结构定义

typedef struct{
	ElemType data[MAXSIZE];	//数组,存储数据元素
	int length;	//线性表当前的长度 
}SqList;

2.获得元素操作


//获得元素操作 
// 初始条件:顺序线性表L已存在,1<=i<=ListLength(L)
//操作结果:用e返回L中第i个数据元素的值,注意i是位置
Status GetElem(SqList L,int i,ElemType *e){
	//首先判断是否为空表以及返回位置是否合法
	if(L.length==0||i<1||i>L.length){
		return ERROR;
	} 
	*e=L.data[i-1];
	
	return OK;
} 

3.插入操作


//插入操作
//初始条件:顺序线性表L已存在,1≤i≤ListLength(L)
//操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1
Status ListInsert(SqList *L,int i,ElemType e){

	//如果顺序表满
	if(L->length==MAXSIZE){
		return ERROR;
	} 
	//插入位置不合法
	if(i<1||i>L->length+1){
		return ERROR;
	} 
	
	if(i<=L->length){
		//将要插入的位置元素后移一位 
		for(int k=L->length-1;k>=i-1;k--){
			L->data[k+1]=L->data[k];
		}
	} 
	//将新元素插入 
	L->data[i-1]=e;
	L->length++;
	
	return OK; 
}

4.删除操作

//删除操作
//初始条件:顺序线性表L已存在,1≤i≤ListLength(L)
// 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1
Status ListDelete(SqList *L,int i,ElemType *e){
	int k;
	//如果线性表为空
	if(L->length==0) {
		return ERROR;
	}
	//删除位置不正确
	if(i<1||i>L->length){
		return ERROR;
	} 
	*e = L->data[i-1];
	//如果删除的是最后一个元素,则不需要下面操作,如果不是,则需要将后面元素向前移动一位
	if(i<L->length){
		for(k=i;k<L->length;k++){
			L->data[k-1]=L->data[k];
		}
	} 
	L->length--;
	return OK;
} 

5.遍历操作

//遍历操作 
//初始条件:顺序线性表L已存在 
//操作结果:依次对L的每个数据元素输出
Status ListTraverse(SqList L)
{
	int i;
    for(i=0;i<L.length;i++)
            visit(L.data[i]);
    cout<<endl; 
    return OK;
}

6.两表合并操作

//将所有的在线性表Lb中但不在La中的数据元素插入到La中
void unionL(SqList *La,SqList Lb){
	int La_len,Lb_len;
	ElemType e;
	//求两个线性表的长度 
	La_len=ListLength(*La);
	Lb_len=ListLength(Lb);
	for(int i=1;i<=Lb_len;i++){
		//取出Lb中第i个元素赋值给e 
		GetElem(Lb,i,&e);
		if(!LocateElem(*La,e)){
			//如果不存在就插入 
			ListInsert(La,++La_len,e);
		}
	}
}

7.完整代码

#include
using namespace std;

//存储空间初始分配量 
#define MAXSIZE 20
 
#define OK 1
#define ERROR 0

//Status 是函数的类型,其值是函数结果状态代码,如OK等 
typedef int Status;
typedef int ElemType;

typedef struct{
	ElemType data[MAXSIZE];	//数组,存储数据元素
	int length;	//线性表当前的长度 
}SqList;


Status visit(ElemType c)
{
    printf("%d ",c);
    return OK;
}

//初始化顺序线性表 
Status InitList(SqList *L) 
{ 
    L->length=0;
    return OK;
}

//初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE
Status ListEmpty(SqList L)
{ 
	if(L.length==0)
		return OK;
	else
		return ERROR;
}

//初始条件:顺序线性表L已存在。操作结果:将L重置为空表 
Status ClearList(SqList *L)
{ 
    L->length=0;
    return OK;
}

// 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 
int ListLength(SqList L)
{
	return L.length;
}

//获得元素操作 
// 初始条件:顺序线性表L已存在,1<=i<=ListLength(L)
//操作结果:用e返回L中第i个数据元素的值,注意i是位置
Status GetElem(SqList L,int i,ElemType *e){
	//首先判断是否为空表以及返回位置是否合法
	if(L.length==0||i<1||i>L.length){
		return ERROR;
	} 
	*e=L.data[i-1];
	
	return OK;
} 

//插入操作
//初始条件:顺序线性表L已存在,1≤i≤ListLength(L)
//操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1
Status ListInsert(SqList *L,int i,ElemType e){

	//如果顺序表满
	if(L->length==MAXSIZE){
		return ERROR;
	} 
	//插入位置不合法
	if(i<1||i>L->length+1){
		return ERROR;
	} 
	
	if(i<=L->length){
		//将要插入的位置元素后移一位 
		for(int k=L->length-1;k>=i-1;k--){
			L->data[k+1]=L->data[k];
		}
	} 
	//将新元素插入 
	L->data[i-1]=e;
	L->length++;
	
	return OK; 
}


//删除操作
//初始条件:顺序线性表L已存在,1≤i≤ListLength(L)
// 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1
Status ListDelete(SqList *L,int i,ElemType *e){
	int k;
	//如果线性表为空
	if(L->length==0) {
		return ERROR;
	}
	//删除位置不正确
	if(i<1||i>L->length){
		return ERROR;
	} 
	*e = L->data[i-1];
	//如果删除的是最后一个元素,则不需要下面操作,如果不是,则需要将后面元素向前移动一位
	if(i<L->length){
		for(k=i;k<L->length;k++){
			L->data[k-1]=L->data[k];
		}
	} 
	L->length--;
	return OK;
} 

//遍历操作 
//初始条件:顺序线性表L已存在 
//操作结果:依次对L的每个数据元素输出
Status ListTraverse(SqList L)
{
	int i;
    for(i=0;i<L.length;i++)
            visit(L.data[i]);
    cout<<endl; 
    return OK;
}


//初始条件:顺序线性表L已存在
// 操作结果:返回L中第1个与e满足关系的数据元素的位序。
// 若这样的数据元素不存在,则返回值为0 
int LocateElem(SqList L,ElemType e)
{
    int i;
    if (L.length==0)
            return 0;
    for(i=0;i<L.length;i++)
    {
            if (L.data[i]==e)
                    break;
    }
    if(i>=L.length)
            return 0;

    return i+1;
}


//将所有的在线性表Lb中但不在La中的数据元素插入到La中
void unionL(SqList *La,SqList Lb){
	int La_len,Lb_len;
	ElemType e;
	//求两个线性表的长度 
	La_len=ListLength(*La);
	Lb_len=ListLength(Lb);
	for(int i=1;i<=Lb_len;i++){
		//取出Lb中第i个元素赋值给e 
		GetElem(Lb,i,&e);
		if(!LocateElem(*La,e)){
			//如果不存在就插入 
			ListInsert(La,++La_len,e);
		}
	}
}


int main(){
	cout<<"新建线性表L1"<<endl;
	SqList L1;
	cout<<"插入元素"<<endl; 
	for(int i=0;i<8;i++){
		//ListInsert(SqList *L,int i,ElemType e)
		//一直在表头插入元素 
		ListInsert(&L1,1,i);
	}
	
	cout<<"获取L1表的长度:"<<ListLength(L1)<<endl;
	
	cout<<"遍历线性表L1"<<endl;
	ListTraverse(L1);
	
	cout<<endl;
	
	cout<<"新建线性表L2"<<endl; 
	SqList L2;
	cout<<"插入元素"<<endl; 
	for(int i=9;i<=14;i++){
		//ListInsert(SqList *L,int i,ElemType e)
		//一直在表头插入元素 
		ListInsert(&L2,1,i);
	}
	cout<<"获取L2表的长度:"<<ListLength(L2)<<endl;
	cout<<"遍历线性表L2"<<endl;
	ListTraverse(L2);
	cout<<endl;
	
	
	//合并线性表
	cout<<"合并两个线性表"<<endl; 
	unionL(&L1,L2);
	cout<<"重新遍历L1"<<endl;
	ListTraverse(L1);
	return 0; 
	
}

2.线性表链式存储结构

1.链式存储结构定义

//线性表的单链表存储结构 
typedef struct Node{
	ElemType data;
	struct Node *next; 
}Node;

typedef struct Node *LinkList;


Status visit(ElemType c)
{
   	cout<<c<<endl;
    return OK;
} 

2.读取元素

//单链表读取
//初始条件:链式线性表L已存在,1<=L<=ListLength(L)
//操作结果:用e返回L中第i个数据元素的值
Status GetElem(LinkList L,int i,ElemType *e){
	int j;
	LinkList p;	//声明一结点p
	p=L->next;	//p指向L的第一个结点
	j = 1;
	while(p&&j<i){
		p=p->next;
		++j;
	} 
	//第i个元素不存在 
	if(!p||j>i){
		return ERROR;
	}
	//取出第i个元素 
	*e=p->data;
	return OK;
} 

3.插入操作

//插入操作
//初始条件:链式线性表L已存在,1≤i≤ListLength(L),
// 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 
Status ListInsert(LinkList *L,int i,ElemType e){
	int j;
	LinkList p,s;
	p=*L;
	j=1;
	//寻找第i个结点 
	while(p&&j<i){
		p=p->next;
		++j;
	}
	if(!p||j>i){
		//第i个元素不存在
		return ERROR; 
	} 
	s = (LinkList)malloc(sizeof(Node));//生成新结点 
	s->data=e;
	s->next=p->next;	//将p的后记结点赋值给s后继 
	p->next=s;	//将s赋值给p的后继 
	
	return OK;
}  

4.删除操作

//删除操作
// 初始条件:链式线性表L已存在,1≤i≤ListLength(L) 
// 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 
Status ListDelete(LinkList *L,int i,ElemType *e){
	int j;
	LinkList p,q;
	p=*L;
	j=1;
	//遍历寻找第i个元素 
	while(p->next&&j<i){
		p=p->next;
		++j;
	}
	if(!(p->next)||j>i){
		return ERROR;
	} 
	
	q=p->next;
	p->next=q->next;
	*e=q->data;
	free(q);
	
	return OK;
}

5.随机产生数,头插法建立线性表

//随机产生n个元素的值,建立带表头结点的单链线性表L(头插法)
void CreateListHead(LinkList *L,int n){
	LinkList p;
	int i;
	//初始化随机数种子 
	srand(time(0));
	*L=(LinkList)malloc(sizeof(Node));
	(*L)->next = NULL;
	for(i=0;i<n;i++){
		p=(LinkList)malloc(sizeof(Node));	//生成新结点
		p->data=rand()%100+1;
		p->next=(*L)->next;
		(*L)->next=p; //插入到表头 
		
	} 
	
} 

6.随机产生数,尾插法建立线性表

// 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法)
void CreateListTail(LinkList *L,int n){
	LinkList p,r;
	int i;
	srand(time(0));
	*L=(LinkList)malloc(sizeof(Node));	//L为整个线性表 
	r=*L;	//r为指向尾部的结点
	for(i=0;i<n;i++){
		p=(Node*)malloc(sizeof(Node));
		p->data=rand()%100+1;
		r->next=p;
		r=p;
	} 
	r->next=NULL;
	
}

7.完整代码

#include
#include "string.h"
#include "ctype.h"      
#include "stdlib.h"   
#include "math.h"  
#include "time.h"
using namespace std;


#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20 //储空间初始分配量

typedef int Status;// Status是函数的类型,其值是函数结果状态代码,如OK等 
typedef int ElemType;// ElemType类型根据实际情况而定,这里假设为int 



//线性表的单链表存储结构 
typedef struct Node{
	ElemType data;
	struct Node *next; 
}Node;

typedef struct Node *LinkList;


Status visit(ElemType c)
{
   	cout<<c<<endl;
    return OK;
} 



// 初始化链式线性表 
Status InitList(LinkList *L) 
{ 
    *L=(LinkList)malloc(sizeof(Node)); //产生头结点,并使L指向此头结点 
    if(!(*L)) //存储分配失败
            return ERROR;
    (*L)->next=NULL; //指针域为空 

    return OK;
}

// 初始条件:链式线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE 
Status ListEmpty(LinkList L)
{ 
    if(L->next)
            return FALSE;
    else
            return TRUE;
}

//初始条件:链式线性表L已存在。操作结果:将L重置为空表 
Status ClearList(LinkList *L)
{ 
	LinkList p,q;
	p=(*L)->next;	//p指向头结点
	while(p){
		q=p->next;
		free(p);
		p=q;
	} 
	(*L)->next=NULL;
	
	return OK;
	
}

//初始条件:链式线性表L已存在。操作结果:返回L中数据元素个数 
int ListLength(LinkList L)
{
    int i=0;
    LinkList p=L->next; /* p指向第一个结点 */
    while(p)                        
    {
        i++;
        p=p->next;
    }
    return i;
}

//单链表读取
//初始条件:链式线性表L已存在,1<=L<=ListLength(L)
//操作结果:用e返回L中第i个数据元素的值
Status GetElem(LinkList L,int i,ElemType *e){
	int j;
	LinkList p;	//声明一结点p
	p=L->next;	//p指向L的第一个结点
	j = 1;
	while(p&&j<i){
		p=p->next;
		++j;
	} 
	//第i个元素不存在 
	if(!p||j>i){
		return ERROR;
	}
	//取出第i个元素 
	*e=p->data;
	return OK;
} 

//初始条件:链式线性表L已存在 
//操作结果:返回L中第1个与e满足关系的数据元素的位序。 
//若这样的数据元素不存在,则返回值为0 
int LocateElem(LinkList L,ElemType e)
{
    int i=0;
    LinkList p=L->next;
    while(p)
    {
        i++;
        if(p->data==e) /* 找到这样的数据元素 */
                return i;
        p=p->next;
    }
    return 0;
}

//插入操作
//初始条件:链式线性表L已存在,1≤i≤ListLength(L),
// 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 
Status ListInsert(LinkList *L,int i,ElemType e){
	int j;
	LinkList p,s;
	p=*L;
	j=1;
	//寻找第i个结点 
	while(p&&j<i){
		p=p->next;
		++j;
	}
	if(!p||j>i){
		//第i个元素不存在
		return ERROR; 
	} 
	s = (LinkList)malloc(sizeof(Node));//生成新结点 
	s->data=e;
	s->next=p->next;	//将p的后记结点赋值给s后继 
	p->next=s;	//将s赋值给p的后继 
	
	return OK;
}  

//删除操作
// 初始条件:链式线性表L已存在,1≤i≤ListLength(L) 
// 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 
Status ListDelete(LinkList *L,int i,ElemType *e){
	int j;
	LinkList p,q;
	p=*L;
	j=1;
	//遍历寻找第i个元素 
	while(p->next&&j<i){
		p=p->next;
		++j;
	}
	if(!(p->next)||j>i){
		return ERROR;
	} 
	
	q=p->next;
	p->next=q->next;
	*e=q->data;
	free(q);
	
	return OK;
}


//初始条件:链式线性表L已存在 
// 操作结果:依次对L的每个数据元素输出 
Status ListTraverse(LinkList L)
{
    LinkList p=L->next;
    while(p)
    {
        visit(p->data);
        p=p->next;
    }
    cout<<endl;
    return OK;
}

//随机产生n个元素的值,建立带表头结点的单链线性表L(头插法)
void CreateListHead(LinkList *L,int n){
	LinkList p;
	int i;
	//初始化随机数种子 
	srand(time(0));
	*L=(LinkList)malloc(sizeof(Node));
	(*L)->next = NULL;
	for(i=0;i<n;i++){
		p=(LinkList)malloc(sizeof(Node));	//生成新结点
		p->data=rand()%100+1;
		p->next=(*L)->next;
		(*L)->next=p; //插入到表头 
		
	} 
	
} 

// 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法)
void CreateListTail(LinkList *L,int n){
	LinkList p,r;
	int i;
	srand(time(0));
	*L=(LinkList)malloc(sizeof(Node));	//L为整个线性表 
	r=*L;	//r为指向尾部的结点
	for(i=0;i<n;i++){
		p=(Node*)malloc(sizeof(Node));
		p->data=rand()%100+1;
		r->next=p;
		r=p;
	} 
	r->next=NULL;
	
}

int main()
{        
    LinkList L1;
    ElemType e;
    Status i;
    int j,k;
    i=InitList(&L1);
    cout<<"新建单链表L1"<<endl;
    cout<<"表头插入数据1-5"<<endl;
    for(j=1;j<=5;j++)
            i=ListInsert(&L1,1,j);
    cout<<"遍历L1:"<<endl;
    ListTraverse(L1); 
    
    cout<<endl;
	cout<<"再在L1表头插入1-10"<<endl; 
    for(j=1;j<=10;j++)
            ListInsert(&L1,j,j);
    cout<<"遍历L1:"<<endl;
    ListTraverse(L1); 

    GetElem(L1,5,&e);
    cout<<"L1第五个元素为"<<e<<endl;



    j=5; 
    ListDelete(&L1,j,&e);
    cout<<"删除第五个数据"<<e<<endl;
    

    printf("再次遍历L1:");
    ListTraverse(L1); 

    i=ClearList(&L1);
    cout<<"清空L1"<<endl;
	 
	 
	CreateListHead(&L1,5);
    cout<<"使用头插法整体创建L1"<<endl; 
    ListTraverse(L1); 

 	i=ClearList(&L1);
    cout<<"清空L1"<<endl;
    
    CreateListTail(&L1,5);
    cout<<"使用尾插法整体创建L1"<<endl; 
    ListTraverse(L1); 


    return 0;
}

上述完整代码均可运行成功。

你可能感兴趣的:(数据结构,数据结构,链表,算法)