单链表的增删改查

重要操作:

p=L;//p指向头结点
p=L->next;//p指向首元结点
p=p->next;//p指向下一个结点

插入操作示意图:插入操作的关键是i-1

 

删除操作:删除操作的关键是  i-1 和  i+1

尾插法:

1.生成头结点
2.头结点指针域置空
3.尾指针r指向头结点
进入循环:
4.生成新结点,p指向新结点
5.输入p的数据
6.p的指针域置空,r的指针域指向p
7.r指向新的尾结点p(此时r成为了p结点)

 

具体代码如下:

#include <iostream>
using namespace std;
#include <stdlib.h>
#define OK 1
#define ERROR -1
typedef int Status;
typedef int Elemtype;
typedef struct LNode{//结点的两个属性 
	Elemtype data;//数据域		 
	struct LNode *next;	//指向下一个结点的指针(指针变量名叫next) //嵌套定义—因为next指针指向的下一个结点还是有这两个属性,所以用嵌套定义 
}LNode,*LinkList;//将结构体类型struct LNode重命名为LNode//将struct LNode *重命名为LinkList

int length=0;//为了方便后面判断元素在表长的什么位置 

//初始化链表 
Status InitList(LinkList &L){//要改变表的都要用&	
	L=new LNode;	//生成新结点(开辟一个空间)作为头结点,用  头指针L 指向头结点 
	L->next=NULL;	//头结点的指针域置空(next是结构体指针L的属性,C++用L.next表示) 
	return OK;
}
//前插法 
void CreateList_former(LinkList &L,int n){
	cout<<"请输入"<<n<<"个"<<"元素到链表中:"<<endl; 
	L=new LNode;//先生成头结点 
	L->next=NULL;//头结点的指针域置空 
	for(int i=0;i<n;i++){
		LinkList p=new LNode;//生成新结点p
		cin>>p->data;//输入元素值赋给新结点p的数据域 
		p->next=L->next; L->next=p; //将新结点插入头结点之后 
		length++; //方便判断表长 
	}	
}
//后插法 
void CreateList_latter(LinkList &L,int n){
	cout<<"请输入"<<n<<"个"<<"元素到链表中:"<<endl; 
	L=new LNode;//先生成头结点
	L->next=NULL;//头结点的指针域置空 
	LinkList r=L;//定义一个尾指针r指向头结点 
	for(int i=0;i<n;i++){
		LinkList p=new LNode;//生成新结点 
		cin>>p->data;
		p->next=NULL; r->next=p;//将新结点*p插入尾结点*r之后 
		r=p;//r指向新的尾结点*p 
		length++; //方便判断表长  
	} 
}
//插入
Status ListInsert(LinkList &L,int i,Elemtype e){
	cout<<"在第"<<i<<"个位置插入元素"<<e<<"后:"<<endl;
	//查找操作
	LinkList p=L; int j=0;//p指向头结点 
	while( p && (j<i-1) ){//j等于i-1时跳出循环 (画图好理解)
		p=p->next;	++j;//查找第i-1个结点,p指向该结点 
	} 
	if(!p||j>i-1)return ERROR;//i大于表长+1或者小于1,插入位置非法 
	//插入操作
	LinkList s=new LNode;//生成新结点
	s->data=e;//将结点s的数据域置为e
	s->next=p->next;//将p的指针域赋给s的指针域 //先后顺序不能反,否则s会指向自己 
	p->next=s;//结点p的指针域指向结点s
	return OK; 
}
//删除
Status ListDelete(LinkList &L,int i){
	cout<<"删除第"<<i<<"个元素后:"<<endl;
	//查找操作 
	LinkList p=L; int j=0;//p指向头结点
	while( (p->next) && (j<i-1) ){//寻找第i个结点,此时p指向其前驱结点 
		p=p->next; ++j;
	}
	if( !(p->next) || (j>i-1) )return ERROR;
	//赋值操作 
	LinkList q=p->next;//临时保存被删除结点的地址到指针q里以备释放
	p->next=q->next;//改变删除结点 前驱结点的指针域(跳过删除的结点直接指向下一个) 
	delete q;//释放删除结点的空间 
	return OK; 
} 
//查找
Status SeekElem(LinkList L,Elemtype e){	//指针函数(LNode *) 返回的是地址 
	LinkList p=L->next;//初始化,p指向首元结点,即p变成首元结点
	int cnt=1;
	while(p&&p->data!=e){//当指针p不为空,且结点值与目标值不同时进入循环 
		cnt++;
		p=p->next;//p指向下一个结点,即p变成下一个结点
	}
	if(cnt>length){
		cout<<"该元素不在此表内"<<endl;
	}
	else
	{cout<<e<<"在第"<<cnt<<"个位置"<<endl;}//查找成功返回e的结点地址,查找失败p为NULL 
} 
//取值
Status GetElem(LinkList L,int i,Elemtype &e){
	//查找操作 
	LinkList p=L->next; int j=1;//p指向首元结点 
	while(p&&j<i){//当j=i时,跳出循环 
		p=p->next;//p指向下一个结点,即p变成下一个结点
		++j;
	}
	if(!p||j>i) return ERROR;//如果 i<1 或 p指针指向的结点为空 跳出循环 
	//赋值操作 
	e=p->data;
	cout<<"该表中第"<<i<<"个元素是"<<e<<endl; 
	return OK;
} 
//输出 
Status printList(LinkList &L){
	if(L==NULL) return ERROR;
	LinkList p=L;//L的地址赋值给p,指针p指向L(L此时为头结点) 
	p=p->next;//p现在为首元结点了 
	while(p){//不知道循环次数的用while 
		cout<<p->data<<" ";
		p=p->next;//p指向下一个结点,即p变成下一个结点
	}
	cout<<endl;
}
//销毁:从头指针开始,依次释放所有结点 
Status DestroyList(LinkList &L){
	while(L){//循环条件为 L非空,即当前所指的结点不是空结点就反复执行 
		LinkList p=L;//将L的地址赋值给p,p就指向了头结点 
		L=L->next;//L指向下一个结点的地址,L变成了下一个结点 
		delete p;//删除p所指的结点 
	}
	return OK; 
} 
/*
	清空链表:依次释放所有结点,并将头结点指针域设置为空 
	(注意清空操作链表还存在,但链表中无元素,成为空链表(头指针和头结点还在),而销毁操作是清空所有内存)	
*/
Status ClearList(LinkList &L){
	LinkList p,q;
	p=L->next;//p指向首元结点 
	while(p){//判断是否到表尾 
		q=p->next;
		delete p;
		p=q;
	}
	L->next=NULL;//头结点指针域为空
	return OK; 
}
//问:在单链表L的两个数据元素a和b间插入x,写出插入x的算法实现,并写程序进行验证
//假设链表L是:1 2 a b 3 
Status test(LinkList&L,Elemtype a,Elemtype b,Elemtype x){
    LinkList p = L;
    p = p->next;//指针p指向下一个结点,即p变成下一个结点 
    while(p){
        if(p->data == a) {
        	break;
		}
		else { p = p->next; }; 
    }
    LinkList q = p->next;//指针q指向p下一个结点,即q变成p的下一个结点
    if(p==NULL || q==NULL) return ERROR;
    else{
        LinkList s= new LNode;//创建新结点,数据域为x 
        s->data = x;
        s->next = p->next;
        p->next = s;
    }
    return OK;
}

int main(){
	LinkList L;//指向头结点的指针就代表了整个链表 
	InitList (L);
	CreateList_former(L,5);
//	CreateList_latter(L,6); 
	cout<<"链表元素依次是:";
	printList(L);
	//插入
	ListInsert(L,1,99);  
	printList(L);
	//删除 
	ListDelete(L,3);
	printList(L);
	//查找
	SeekElem(L,2);
	//销毁
	DestroyList(L); 
	cout<<"销毁链表后:"<<endl;
	printList(L);
	return 0;
} 

运行结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值