C语言实现线性表

前言

本篇博客使用c、c++实现了线性表的增删改查,实现方式分为链表与顺序表 。代码复制粘贴可运行。
后续算法均基于本博客cpp 文件"sqlist"与"linknode"实现。


一、基于数组的顺序表

1、实现

//本文件为 sqlist,main函数随后
#include <cstdio>
#include <iostream>
#include <malloc.h>
//#define MAXSIZE 100
typedef int ElemType;
using namespace std;


typedef struct SqList{
		ElemType data[100];
		int length;
}SqList;

void InitList(SqList * &L)
{
	//L=new (SqList);
	L=(SqList *)malloc(sizeof(SqList));
	L->length=0;
}
void CrearList(SqList * &L)
{
	int n;
	cout<<"请输入您需要储存元素的数量"<<endl;
    cin>>n;
    L->length=n;
    cout<<"请输入您需储存的元素"<<endl;
    for(int i=0;i<L->length;i++)
    {
		ElemType x;
		cin>>x;
    	L->data[i]=x;
	}
}

void DestroyList(SqList *&L)
{
	free(L);
}

bool ISEmpty(SqList *&L)
{
	return L->length==0;
}

int ListLength(SqList *&L)
{
	return L->length;
}

void DispList(SqList *&L)
{
	if(L->length>0)
	{
		cout<<"表中的值为:"<<endl;
			for(int i=0;i<L->length;i++)
				{
					cout<<L->data[i]<<endl;
				}
	}
	else
	cout<<"表中没有元素哦"<<endl;
}

bool GetElem(SqList *&L,int i,ElemType &e)//注意此处e为引用传递
{
	if(i>0&&i<=L->length)
	{
	e = L->data[i-1];
	return true;
	}
	else
	return false;
}

bool LocateElem(SqList *&L,ElemType e)//若存在e,则返回True
{
		for(int i=0;i<L->length;i++)
	{
		if(L->data[i]==e)
	        return true;
		else
	     	return false;
	}
}

bool ListInsert(SqList *&L,int i,ElemType e)//将值为e的元素插在第i个位置
{
	if(i<0||i>L->length)
		return -1;
	else
	{
		int j=i-1;
		for(int k=L->length-1;k>j;k--)//1 2 3 4 5
	  		L->data[k+1]=L->data[k];
			L->data[j]=e;
			L->length++;
	}
	return 0;
}

bool ListDelete(SqList *&L,int i,ElemType &e)//将第i个位置的值用e返回并删除i
{
 	 if(i<0||i>L->length)
	  		 return false; // 1 2 3 4 5 5 5
     else
	   {
	     	e=L->data[i-1];
	     	for(int j=i-1;j<L->length-1;j++)
	     	L->data[j]=L->data[j+1];
	     	L->length--;
	   }
	   return 0;
}

2、测试代码

//main函数测试代码:
int main(){
	SqList *L;
	InitList(L);
	CrearList(L);
		cout<<"表的长度为:"<<ListLength(L)<<endl;
	DispList(L);
	
	ElemType e;
	GetElem(L,3,e);
 	    cout<<"表中第三个元素为:"<<e<<endl;

	ListDelete(L,1,e);
		cout<<"删除的值为:"<<e<<endl;
	//cout<<"删除后的表为:"<<endl;
	DispList(L);
	
	//ISEmpty(L);
	cout<<"现在第一个位置插入元素 8"<<endl;
	ListInsert(L,1,8);
	cout<<"表的长度为:"<<ListLength(L)<<endl;
	DispList(L);
	
	ListDelete(L,1,e);
	cout<<"删除的值为:"<<e<<endl;
	//cout<<"删除后的表为:"<<endl;
	DispList(L);
	
	if(LocateElem(L,3))
		cout<<"表中存在元素3"<<endl;
	else
		cout<<"表中不存在元素3"<<endl;

	DestroyList(L);


	return 0;
}

二、基于链式存储的线性表

1、实现

//本文文件为<linknode>
#include <cstdio>
#include <iostream>
#include <malloc.h>
#include <assert.h>
//#define MAXSIZE 100
typedef int ElemType;
using namespace std;


typedef struct LinkNode{
		ElemType data;
		struct LinkNode *next;
}LinkNode;

void InitList(LinkNode * &L)
{
	//L=new (LinkNode);
	L=(LinkNode *)malloc(sizeof(LinkNode));
	L->next=NULL;
}

void CrearListR(LinkNode * &L,ElemType a[],int n)//用a[]初始化链表,n为数组长度,尾插法实现
{
	 L=(LinkNode *)malloc(sizeof(LinkNode));
	 L->next=NULL;
	 LinkNode *s;
     LinkNode *r=L;
	 for(int i=0;i<n;i++)
	 {
	 	s=(LinkNode *)malloc(sizeof(LinkNode));
	 	s->data=a[i];
		r->next=s;
	//	s->next=NULL;
		r=s;
	 }
	  r->next=NULL;
}

void CreatListF(LinkNode * &L,ElemType a[],int n)//头插法建立链表
{
	 L=(LinkNode *)malloc(sizeof(LinkNode));
	 L->next=NULL;
	 LinkNode *p=L;
	 LinkNode *s;
	 for(int i=0;i<n;i++)
	 {
	 	 s=(LinkNode*)malloc(sizeof(LinkNode));
	 	 s->data=a[i];
	 	 s->next=p->next;
	 	 p->next=s;
	 }
}

void DestroyList(LinkNode *&L)
{
	LinkNode *pre=L,*p=pre->next;
	while(p!=NULL)
	{
		free(pre);
		pre=p;
		p=pre->next;
	}
	free(pre);//此时p指向NULL,而pre指向尾结点
}

void DispList(LinkNode *&L)//打印链表需建立在链表非空情况下
{
	LinkNode *p=L->next;
	 while(p!=NULL)
	 {
		cout<<p->data<<endl;
	 	p=p->next;
	 }
}

bool ISEmpty(LinkNode *&L)
{
	return L->next==NULL;
}

int ListLength(LinkNode *&L)
{
	int length=0;
    LinkNode *p=L->next;
    while(p!=NULL)
    {
    	length=length+1;
    	p=p->next;
	}
	return length;
}

bool GetElem(LinkNode *&L,int i,ElemType &e)//注意此处e为引用传递
{
	 if(i<=0)
	 return false;
	 else
	 {
	 	int j=1;
	    LinkNode *p=L->next;//此处有多种写法:j=0/p=L/j<i-1...
		while(j<i&&p!=NULL) 
		{
			p=p->next;
			j++;
		}
		if(p!=NULL)
		{
            e=p->data;
            return true;
		}
		else
			return false;
	 }
}

bool LocateElem(LinkNode *&L,ElemType e)//若存在e,则返回True、、此函数可写成返回e的位置
{
	 LinkNode *p=L->next;
	 while(p!=NULL)//此处可写成p->data!=e
	 {
	 	if(p->data==e)
	 	return true;
	 	else
	 	p=p->next;
	 }
}

bool ListInsert(LinkNode *&L,int i,ElemType e)//将值为e的元素插在第i个位置
{
	if(i<=0)
	return false;
	else
	{
		 int j=0;//此处不同与GetElem
 	     LinkNode *p=L;//因存在操作第一个元素的可能,故此处 p 不能赋值 L-1
		 while(p!=NULL&&j<i-1)
		 {
	 	    p=p->next;
		 	j=j+1;
		 }
		 if(p!=NULL)
		 {
    	    LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
 			s->data=e;
		 	s->next=p->next;
	 		p->next=s;
		 	 return true;
		 }
		 else
		 	 return false;
	}

	 
}

bool ListDelete(LinkNode *&L,int i,ElemType &e)//将第i个位置的值用e返回并删除i
{
	if(i<=0)
	return false;
	 int j=1;
	 LinkNode *p=L,*s;
	 while(p!=NULL&&j<i)// 1 1 1 1 1 1
	 {
	 	p=p->next;
	 	j=j+1;
	 }
	 if(p==NULL)
        return false;
	 else
	 {
	 	//LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
	 	s=p->next;
	 	if(s==NULL)
		   return false;
	 	e=s->data;
	 	p->next=s->next;
	 	free(s);
	 	return true;
	 }
	 
}

2、测试代码

int main(){
	LinkNode *L;
	
	InitList(L);
	ElemType a[10]={1,2,3,4,5,6,7,8,9,10};
	CrearListR(L,a,10);
        cout<<"表的长度为:"<<ListLength(L)<<endl;
	DispList(L);
	
	ElemType e;
	GetElem(L,1,e);
		cout<<"表的第一个元素为"<<e<<endl;
		cout<<"现在将"<<e<<"这个元素插入第一个位置:"<<endl;
	ListInsert(L,1,e);
	    cout<<"表的长度为:"<<ListLength(L)<<endl;
		cout<<"修改后的表为:"<<endl;
	DispList(L);
	
	cout<<"若表非空,则删除第三个元素"<<endl;
 		ListDelete(L,3,e);
	cout<<"删除的元素为:"<<e<<endl;
	cout<<"表的长度为:"<<ListLength(L)<<endl;
	cout<<"删除后的表为:"<<endl;
	DispList(L);
	
	if(LocateElem(L,3))
		cout<<"表中存在元素3"<<endl;
	else
		cout<<"表中不存在元素3"<<endl;
	DestroyList(L);
	return 0;
}

三、测试结果


在这里插入图片描述

在这里插入图片描述

总结

之后的博客将看到一些算法逐步求精的过程,他们的存储结构将基于上述实现。还请大家发现、纠正可能存在的错误!感谢阅读本篇博客!
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七月是你的谎言..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值