#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct LNode{
int data;//数据元素
struct LNode *next; //指向后续结点
}LinkNode;
//线性表 -————单链表
int main(){
//函数声明
void GreateListF(LinkNode *&L,int a[],int n);//头插法,输入输出是相反的
void GreateListR(LinkNode *&L,int a[],int n);//尾插法,输入输出顺序相同
void InitList(LinkNode *&L);//初始化
void DestoryList(LinkNode *&L);//销毁线性表
bool ListEmpty(LinkNode *L);//判断是否为空表
int ListLength(LinkNode *L);//线性表的长度
void DisLinkNode(LinkNode *L);//输出线性表
bool GetElem(LinkNode *L,int i,int &e);//求线性表第i个位置的元素
int LocateElem(LinkNode *L,int e);//查找元素的位置(逻辑号,线性表是从1开始)
bool ListInset(LinkNode *&L,int i,int e);//在第i个位置插入数据元素
bool ListDelete(LinkNode *&L,int i,int &e);//删除第i个位置的数据元素
LinkNode *L;
int e;//用于接收函数返回的数值
int a[]={1,2,3,4,5};
GreateListR(L,a,5);
if(ListEmpty(L)){
cout<<"线性表为空"<<'\n';
}else{
cout<<"线性表不为空"<<'\n';
}
cout<<"线性表的长度为:"<<ListLength(L)<<endl;
DisLinkNode(L);//打印线性表
ListInset(L,2,10);//在第2的位置插入一个元素,注意线性表从1开始
cout<<"插入元素后的线性表:"<<endl;
DisLinkNode(L);
ListDelete(L,3,e);
DestoryList(L);//销毁线性表
cout<<"删除成功"<<endl;
return 0;
}
/*---------------------------------------------------------------------------*/
//初始化
void InitList(LinkNode *&L){
L = new LinkNode; //创建头结点
L->next = NULL; //next域置为NULL
}
/*---------------------------------------------------------------------------*/
//头插法,输入输出是相反的
void GreateListF(LinkNode *&L,int a[],int n){
LinkNode *p;
L = new LinkNode;
L->next=NULL;
for(int i =0;i<n;i++){
p = new LinkNode;
p->data = a[i];
//将节点p插入到原节点之前、头结点之后 例:s->q->...改为:s->p->q->...
p->next = L->next;
L->next = p;
}
}
/*---------------------------------------------------------------------------*/
void GreateListR(LinkNode *&L,int a[],int n){
LinkNode *p,*r;//*r尾指针,始终指向最后一个结点
L = new LinkNode;
L->next = NULL;
r=L;//开始将头结点作为尾结点
/*
int n = sizeof(a);//获得数组的长度,注意,不能直接在函数体里面使用sizeof方法,因为形参数组的长度不确定
当把数组作为函数的参数时,你无法在程序运行时通过数组参数本身告诉函数该数组的大小,因为函数的数组参数相
当于指向该数组第一个元素的指针。这意味着把数组传递给函数的效率非常高,也意味着程序员必须通过某种机制告诉
函数数组参数的大小。
*/
for(int i =0;i<n;i++){
p = new LinkNode;
p->data = a[i];
r->next = p;
r = p;//改变尾指针r的指向
}
r->next = NULL;//函数结束时,就r的next域置为NULL
}
/*---------------------------------------------------------------------------*/
//疑问:线性表链式存储,在第2个位置插入,是按:1 2,还是按:0 1 2 的顺序插入?答案:下标为:1的位置
//在第i个位置插入数据元素,采用:头插法
bool ListInset(LinkNode *&L,int i,int e){
int j = 0;
LinkNode *p,*q=L; //q指向L的首节点
while(q!=NULL&&j<i-1){ //找到第i-1个结点
q = q->next;
j++;
}
if(q == NULL){
return false;//插入位错误
}else{
p = new LinkNode; //创建新节点
p->data = e; //赋:数值
p->next = q->next; //将节点p插入到节点q之后,也就是第i个位置
q->next = p; //q指向p节点
return true;
}
}
/*---------------------------------------------------------------------------*/
//删除第i个位置的数据元素
bool ListDelete(LinkNode *&L,int i,int &e){
int j = 0;//用于判断i是否在链表内
LinkNode *p,*q=L;
while(j<i-1&&q!=NULL){ //找到第i-1个结点
q = q->next;
j++;
}
if(q==NULL){//若未找到值,则返回:false
return false;
}else{
p = q->next; //是p指向第i个结点
if(p ==NULL){//如果不存在第i个结点
return false;
}else{
e = p->data;//将该结点的数值域保存
q->next = p->next;//取消 q结点(也就是第i个结点的前后链接
delete p;//销毁p,因为q结点不再指向p,而是指向原来p结点的下一个结点
return true;
}
}
}
/*---------------------------------------------------------------------------*/
//输出
void DisLinkNode(LinkNode *L){
LinkNode *p;
p = L->next; //p指向L:首节点
while(p!=NULL){
cout<<p->data<<" ";
p=p->next;//移动指针
}
cout<<'\n';
}
/*---------------------------------------------------------------------------*/
//销毁线性表
void DestoryList(LinkNode *&L){
LinkNode *pre=L, *p=L->next; //pre指向结点L的前驱结点(首结点)
while(p!=NULL){
delete pre;
pre = p; //p和pre同时往后移动
p = pre->next;
}
delete pre;
}
/*---------------------------------------------------------------------------*/
//判断为空
bool ListEmpty(LinkNode *L){
return L->next==NULL;
}
/*---------------------------------------------------------------------------*/
//获取线性表的长度
int ListLength(LinkNode *L){
int length=0;
LinkNode *p=L;//p指向头结点,length置为0(头结点的序号为:0)
while(p->next!=NULL){
length++;
p = p->next;
}
return length;
}
/*---------------------------------------------------------------------------*/
//求线性表第i个位置的元素
bool GetElem(LinkNode *L,int i,int &e){
LinkNode *p=L;
int j=0;
if(i<0){
return false;
}
while(j<i&&p->next!=NULL){
j++;
p = p->next;
}
if(p==NULL){
return false;
}else{
e = p->data;
return true;
}
}
/*---------------------------------------------------------------------------*/
//查找元素:e的位置(逻辑号,线性表是从1开始)
int LocateElem(LinkNode *L,int e){
int j = 1;
LinkNode *p = L;
while(p!=NULL&&p->data!=e){
p = p->next;
j++;
}
if(p!=NULL){
return j;//如果存在x元素,则返回逻辑号:j
}else{
return 0;//如不存在,则返回:0
}
}
线性表的链式存储(单链表)
最新推荐文章于 2022-06-27 20:47:23 发布