单链表的基本操作


# include <stdio.h>
# include <stdlib.h>
typedef struct Linknode {
	char data;
	struct Linknode* next;
}*Linklist, Lnode;

// 初始化一个带头结点的链表
Linklist initlinklist() {
	Linklist node = new Lnode;
	node->data = '\0';
	node->next = NULL;
	return node;
}

// 输出函数,输出链表里的元素
void outputlinklist(Linklist L) {
	Linklist p = L;
	p = p->next;
	printf("链表内的元素有: \n");
	while (p != NULL)
	{
		printf("%c ", p->data);
		p = p->next;
	}
	printf("\n");
}

// 在链表的末尾添加元素
void appendlinklist(Linklist L, char element) {
	Linklist p;
	p = L;
	while (p->next != NULL) {
		p = p->next;
	}
	Linklist q = new Lnode;

	q->data = element;
	q->next = NULL;
	p->next = q;
}

// 在链表中插入元素
void insertlinklist(Linklist L, int num, char element) {
	Linklist p = L;
	Linklist q = new Lnode;
	q->data = element;
	if (num < 0) {
		printf("插入位置不能是负数\n");           //判断插入位置是否为负数
		return;
	}
	int i;
	for (i = 0; i < num; i++){
		p = p->next;
		if (p == NULL)
		{
			printf("插入位置不正确\n");
			return;
		}
	}
	q->next = p->next;
	p->next = q;
}

Linklist getelement(Linklist L, char element) {
	Linklist p = L;
	p = p->next;
	while (p != NULL && p->data != element) {
		p = p->next;
	}
	if (p->data == element)
		return p;
	else
		printf("查抄失败,该元素不存在\n");
}
// 从链表中删除元素
void deletelinklist(Linklist L, char element) {
	Linklist p = L;
	while (p->next != NULL) {
		if (p->next->data == element)
		{
			break;
		}
		p = p->next;
	}
	if (p->next == NULL)
	{
		printf("链表中无%c,无法删除\n",element);
		return;
	}
	p->next = p->next->next;
}

// 测试添加,插入,删除函数
void append_insert_deletetest()
{
	// step1 先建立一个有头结点的链表
	Linklist testlist = initlinklist();
	outputlinklist(testlist);

	// step2 测试添加函数
	printf("现在进行添加函数的测试\n");
	printf("\n");
	appendlinklist(testlist, 'H');
	appendlinklist(testlist, 'e');
	appendlinklist(testlist, 'l');
	appendlinklist(testlist, 'l');
	appendlinklist(testlist, 'o');
	outputlinklist(testlist);
	printf("结束添加函数测试\n");
	printf("\n");

	// step3 测试删除函数
	printf("现在进行删除函数的测试\n");
	printf("\n");
	deletelinklist(testlist, 'e');
	deletelinklist(testlist, 'a');
	deletelinklist(testlist, 'o');
	outputlinklist(testlist);
	printf("结束删除函数测试\n");
	printf("\n");

	// step4 测试插入函数
	printf("现在进行插入函数的测试\n");
	printf("\n");
	insertlinklist(testlist, 1, 'o');
	outputlinklist(testlist);
	printf("结束插入函数测试\n");
	printf("\n");
}


// 地址测试

void basicAddressTest() {
	Lnode tempNode1, tempNode2;
	tempNode1.data = 4;
	tempNode1.next = NULL;
	tempNode2.data = 6;
	tempNode2.next = NULL;
	printf("The first node: %p, %p, %p\r\n", &tempNode1, &tempNode1.data, &tempNode1.next);
	printf("The second node: %p, %p,%p\r\n", &tempNode2, &tempNode2.data, &tempNode2.next);
	tempNode1.next = &tempNode2;
}

// 插入函数测试
void inserttestlist() {
	Linklist p = initlinklist();
	insertlinklist(p, 0, 'H');
	outputlinklist(p);
	insertlinklist(p, 1, 'e');
	outputlinklist(p);
	insertlinklist(p, 2, 'l');
	outputlinklist(p);
	insertlinklist(p, 3, 'l');
	outputlinklist(p);
	insertlinklist(p, 4, 'o');
	outputlinklist(p);
	insertlinklist(p, -2, 'P');
	outputlinklist(p);
	insertlinklist(p, 8, 'M');
	outputlinklist(p);
}


int main()
{
	append_insert_deletetest();
	inserttestlist();
	return 0;
}

 插入函数图示

在这里插入图片描述

删除函数图示

在这里插入图片描述

插入函数操作:1.定义两个指针,一个用于移动到插入位置,另一个用于创建新节点接入插入位置

 2.进行插入位置的判断,避免插入位置为负数

3.通过for循环,一直循环到插入位置,如果中途指针指向NULL,则说明插入位置不正确

4.如果未出现上述情况,则进行操作q->next=p->next;p->next=q;插入操作完成

删除函数操作:1.定义一个指针用于查找需要删除元素的位置

2.通过while循环,一直循环到删除位置,如果循环结束后仍未找到需要删除的元素,则说明链表中无该元素,那么return结束

3.若找到需要删除元素,则进行操作p->next=p->next->next;删除操作完成

链表的优势:链表不需要预先分配空间,只要空间允许,链表中的元素个数就没有限制。

链表的插入和删除操作无需移动数据,只需要修改指针,时间复杂度为O(1)。对于需要频繁进行插入和删除的线性表,宜采用链表。

劣势:用链表查找元素时,只能从表头开始,依次向后遍历,直到找到第i个位置的元素,时间复杂度为O(n),相较于顺序表更复杂。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qq_73931224

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

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

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

打赏作者

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

抵扣说明:

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

余额充值