数据结构之单链表

本文详细介绍了如何在C++中实现链表的初始化、打印、尾部插入、按位置插入和按值删除操作,涉及动态内存分配、指针使用以及错误处理,有助于理解链表数据结构和相关编程技巧。
摘要由CSDN通过智能技术生成
#include<iostream>
using namespace std;

typedef struct LinkNode{
	char data;
	struct LinkNode* next;
}LNode,*LinkList,*NodePtr;
//定义链表 
LinkList initLinkList(){
	NodePtr tempHeader=(NodePtr)malloc(sizeof(LNode));
	if(tempHeader==NULL)//判断内存是否分配成功 
	exit(0);//分配失败就退出 
	tempHeader->data='\0';
	tempHeader->next=NULL;
	return tempHeader;
}
//初始化链表 
void printList(NodePtr paraHeader){
	NodePtr p=paraHeader->next;
	while(p!=NULL){
	      printf("%c",p->data);
	      p=p->next;
	}
	printf("\r\n");
}
//打印链表 
void appendElement(NodePtr paraHeader, char paraChar){
	NodePtr p,q;
	q=(NodePtr)malloc(sizeof(LNode));
	if(q==NULL)
	exit(0);
	q->data=paraChar;
	q->next=NULL;
	p=paraHeader;
	while(p->next!=NULL){
		p=p->next;
	}
	p->next=q;
}
//尾插法 
void insertElement(NodePtr paraHeader, char paraChar, int paraPosition){
	NodePtr p,q;
	p=paraHeader;
	for(int i=0;i<paraPosition;i++){
		p=p->next;
		if(p==NULL){
			printf("The position %d is beyond the scope of the list.", paraPosition);//判断插入位置是否合理 
			return;
		}
	}
	q=(NodePtr)malloc(sizeof(LNode));
	if(q==NULL)
	exit(0);
	q->data=paraChar;
	q->next==NULL;
	printf("linking\r\n");
	q->next=p->next;
	p->next=q;
}
//在第paraPosition位插入数据 
void deleteElement(NodePtr paraHeader, char paraChar){
	NodePtr p,q;
	p=paraHeader;
	while((p->next!=NULL)&&(p->next->data!=paraChar)){
		p=p->next;
	}
	if(p->next==NULL){
		printf("Cannot delete %c\r\n", paraChar);
		return;
	}
	q=p->next;
	p->next=p->next->next;
	free(q);//释放结点 
}
//按值删除 
void appendInsertDeleteTest(){
	LinkList tempList=initLinkList();
	printList(tempList);
	appendElement(tempList, 'H');
	appendElement(tempList, 'e');
	appendElement(tempList,'l');
	appendElement(tempList,'l');
	appendElement(tempList,'o');
	appendElement(tempList,'!');
	printList(tempList);
	deleteElement(tempList,'e');
	deleteElement(tempList,'a');
	deleteElement(tempList,'o');
	printList(tempList);
	insertElement(tempList,'o',1);
	printList(tempList);
}
void basicAddressTest(){
	LNode tempNode1,tempNode2;
	tempNode1.data=4;
	tempNode1.next=NULL;
	tempNode2.data=6;
	tempNode2.next=NULL;
	printf("The first node: %ld, %ld, %ld\r\n",&tempNode1,&tempNode1.data,&tempNode1.next);
	printf("The second node: %ld, %ld, %ld\r\n",&tempNode2,&tempNode2.data,&tempNode2.next);
	tempNode1.next=&tempNode2;
}
//打印地址 
int main(){
	appendInsertDeleteTest();
	basicAddressTest(); 
	return 0;
}

运行结果:

链表中的重要算法:

尾插法示意图:

插入算法:

删除算法:

学习心得:

  1. 链表的基本操作: 链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在这段代码中,作者实现了链表的初始化、打印、尾部插入、按位置插入和按值删除等基本操作,这些操作是链表常见的基本操作,对于理解链表的工作原理和使用方法非常重要。

  2. 内存分配与释放: 作者使用了动态内存分配函数 malloc() 来为链表节点分配内存空间,并在适当的时候使用 free() 函数释放节点所占用的内存空间。动态内存分配可以让程序在运行时动态地分配内存空间,从而灵活地管理内存资源,但同时也需要注意及时释放已分配的内存空间,以避免内存泄漏问题。

  3. 指针的使用: 在链表的实现过程中,作者频繁地使用了指针来操作节点之间的关系。指针是C++中非常重要的概念,它可以指向内存中的某个地址,并通过对指针的操作来间接地操作所指向的数据。通过这段代码的练习,我更加熟悉了指针的使用方法,包括指针的声明、指针的赋值、指针的解引用等操作。

  4. 错误处理: 在代码中,作者通过一些条件判断语句来处理一些可能出现的错误情况,如内存分配失败时的处理、插入位置越界时的处理等。良好的错误处理机制可以增强程序的健壮性和可靠性,减少程序出错的可能性,提高程序的稳定性。

总的来说,通过编写这段代码并理解其中的各种操作,我对链表的原理和使用方法有了更深入的理解,并且加深了对指针的掌握。这对我后续学习和应用其他数据结构和算法也会有很大的帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值