数据结构--链表 带头节点的各项操作

完整代码如下,全部手打,如有错误,还望斧正

#include<bits/stdc++.h>
using namespace std;
#define ElemType int
/*
	链表操作,带头节点的链表
 */
typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode, *LinkList; //LiskList相当于LNode*,只是为了表达是一个是节点一个是链表的差别
/*
	初始化操作,带头节点
 */
bool init(LinkList &L){
	L = (LNode *)malloc(sizeof(LNode));
	if(L==NULL) return false;	//表示内存分配失败
	L->next = NULL;
	return true;
}
/*
	头插入法
 */
void createListL(LinkList &L, ElemType a[], int n){	//L 要创建的链表, a 输入L中的数据, n 数组a的长度
	LNode *s; //s用来表示新申请的节点

	//以下两行相当于init(L)
	L = (LNode *)malloc(sizeof(LNode));
	L->next = NULL;

	for(int i = 0; i < n; i++){
		s = (LNode *)malloc(sizeof(LNode));		//新节点申请一个空间用来存储数据
		s->data = a[i];	//把a[i]中的数据放入
		s->next = L->next;	
		L->next = s;	//把s节点插入到L中
	}
}
/*
	尾插入法
 */
void createListR(LinkList &L, ElemType a[], int n){	//L 要创建的链表, a 输入L中的数据, n 数组a的长度
	LNode *s, *r; //s用来表示新申请的节点,r表示始终指向L终端的节点

	//以下两行相当于init(L)
	L = (LNode *)malloc(sizeof(LNode));
	L->next = NULL;
	r = L;

	for(int i = 0; i < n; i++){
		s = (LNode *)malloc(sizeof(LNode));		//新节点申请一个空间用来存储数据
		s->data = a[i];	//把a[i]中的数据放入
		r->next = s;	//把s节点插入到L中
		r = r->next;	//r是指向尾指针的,所以要进行更新
	}

	r->next = NULL;
}

/*
	删除节点,看给的条件是什么,
	如果直接给的是一个节点,O(1)复杂度,只需要把其相邻的节点的值交换一下即可,
	前提是删除的节点不是尾节点,如果是尾节点的话还是要O(n)的复杂度
	如果给的是一个值,要删除链表中值为key的第一个节点,那么要O(1)的复杂度,要遍历一遍链表
 */
void deleteLNode1(LNode *node){
	node->data = node->next->data;
	node->next = node->next->next;
}
bool deleteLNode2(LinkList &L, int key){
	LNode *p, *q;
	q = L;
	p = L->next;
	while(p!=NULL){
		if(p->data==key) break;
		p = p->next;
		q = q->next;
	}
	if(p==NULL) return false;	//表示链表中不存在值为key的节点
	else{
		//deleteLNode1(p);	//用到了一个删除的方法,但这个并不完美,因为这个节点不能为最后一个
		q->next = p->next;
	}
	return true;
}



/*
	改变节点
 */
bool changeElem(LinkList L, int i, ElemType key){
	LNode *p = L->next;
	while(p&&i) p = p->next, i--;
	p->data = key;
	return true;
}

/*
	查询节点
 */
LNode *getElem(LinkList L, int i){	//从第0个节点开始计数
	LNode *p = L->next;
	while(p&&i) p = p->next, i--;
	return p;
}
/*
	打印链表
 */
void print(LinkList L){
	L=L->next;
	while(L){
		cout<<L->data<<" ";
		L=L->next;
	}
	cout<<endl;
}
/*
	插入节点,在第i个位置插入key,即第i个位置的值为key
 */
void insertLNode(LinkList &L, int i, ElemType key){
	LNode* p = getElem(L,i-1);	//先找到第i-1个位置
	LNode* s = (LNode *)malloc(sizeof(LNode));
	s->data = key;
	s->next = p->next;
	p->next = s;
}


/*
	主函数,包括对链表的一系列操作和解释
 */
int main(){
	int a[] = {1,2,3,4,5};
	LinkList L1, L2;

	//创建链表,头插法,逆序
	createListL(L1,a,5);
	cout<<"链表L1数据如下:"<<endl;
	print(L1);
	cout<<endl;
	//尾插法,正序
	createListR(L2,a,5);
	cout<<"链表L2数据如下:"<<endl;
	print(L2);
	
	cout<<endl;

	LNode *c = getElem(L2,3); //查询正序第四个元素,我这里的代码是从零开始计算
	cout<<"L2第4个元素的值为: "<<c->data<<endl;

	cout<<endl;

	insertLNode(L2, 3, 33);	//在第四个位置插入33
	cout<<"L2在第四个位置插入一个值:"<<endl;;
	print(L2);

	cout<<endl;

	deleteLNode2(L2,5); //删除链表中第一个值为5的节点
	cout<<"删除链表中第一个值为5的节点后:"<<endl;
	print(L2);

	cout<<endl;

	changeElem(L2,4,99); //更改链表中第四个节点的值
	cout<<"更改链表中第五个节点的值后:"<<endl;
	print(L2);

	cout<<endl;

	return 0;
}

PS:acm过渡到数据结构的全部具体实现还是有那么点的生疏,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值