无头链表再封装方式实现 (C语言描述)

 无头链表再封装方式

#include <stdio.h>
#include <stdlib.h>

//节点数据类型
typedef struct Node {
	int data;
	struct Node* next;
}NODE,*LPNODE;

//链表数据类型
typedef struct List {
	LPNODE frontNode;   //指向表头
	LPNODE tailNode;	//指向表尾
	int listSize;
}LIST, * LPLIST;

//创建数据节点函数
LPNODE createNode(int data) {
	LPNODE newNode = (LPNODE)malloc(sizeof(NODE));
	if (NULL == newNode) {
		printf("数据节点内存申请失败!\n");
		return NULL;
	}
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}

//创建链表
LPLIST createList() {
	LPLIST list = (LPLIST)malloc(sizeof(LIST));
	if (NULL == list) {
		printf("链表节点申请失败!\n");
		return NULL;
	}
	list->tailNode = NULL;
	list->frontNode = NULL;
	list->listSize = 0;
	return list;
}

//判断链表是否为空
int empty(LPLIST list) {
	return list->listSize == 0;
}

//返回链表长度
int size(LPLIST list) {
	return list->listSize;
}

//头插
void insertByHead(LPLIST list, int data) {
	LPNODE newNode = createNode(data);
	if (empty(list)) {
		list->frontNode = newNode;
		list->tailNode = newNode;
	}
	else {
		newNode->next = list->frontNode;
		list->frontNode = newNode;
	}
	list->listSize++;
}

//尾插
void insertByTail(LPLIST list, int data) {
	LPNODE newNode = createNode(data);
	if (empty(list)) {
		list->frontNode = newNode;
		list->tailNode = newNode;
	}
	else {
		list->tailNode->next = newNode;
		list->tailNode = newNode;         //表尾移动到新的表尾
	}
	list->listSize++;
}

//指定插
void insertByAppoint(LPLIST list, int data, int pos) {
	LPNODE newNode = createNode(data);
	if (empty(list)) {
		list->frontNode = newNode;
		list->tailNode = newNode;
	}
	else {
		LPNODE curNode = list->frontNode;
		while (curNode->next != NULL && --pos) {
			curNode = curNode->next;
		}
		newNode->next = curNode->next;
		curNode->next = newNode;
		if (newNode->next == NULL) {   //若插入到表尾, 表尾指针指向新节点
			list->tailNode = newNode;
		}
	}
	list->listSize++;
}

//头删
void deleteByHead(LPLIST list) {
	LPNODE delNode = list->frontNode;
	if (empty(list)) {
		printf("链表为空, 数据删除失败!\n");
		return;
	}
	else {
		if (delNode->next == NULL)
			list->tailNode = NULL;
		list->frontNode = delNode->next;
	}
	free(delNode);
	delNode = NULL;
	list->listSize--;
}

//尾删
void deleteByTail(LPLIST list) {
	LPNODE preNode = list->frontNode;
	LPNODE delNode = list->frontNode;
	if (empty(list)) {
		printf("链表为空,数据删除失败!\n");
		return;
	}
	else {
		if (delNode->next == NULL)
			list->frontNode = NULL;
		while (delNode->next != NULL) {
			preNode = delNode;
			delNode = delNode->next;
		}
		if (list->frontNode == NULL) {
			list->tailNode = NULL;
		}
		else {
			list->tailNode = preNode;
		}
	}
	preNode->next = NULL;
	free(delNode);
	delNode = NULL;
	list->listSize--;
}

//指定数据删除
void deleteByAppoint(LPLIST list, int posData) {
	LPNODE curNode = list->frontNode;
	LPNODE preNode = list->frontNode;   //保存删除节点的前一个节点
	if (empty(list)) {
		printf("链表为空,数据删除失败!\n");
		return;
	}
	if (curNode->data == posData) { //第一个节点且就是指定删除数据
		if (curNode->next == NULL) { //只有一个节点
			list->frontNode = NULL;
			list->tailNode = NULL;
		}
		else {   //后面还有节点
			list->frontNode = curNode->next;
		}
		preNode = NULL;
	}
	else {  //删除节点在第一个节点之后
		while (curNode->next != NULL && curNode->data != posData) {
			preNode = curNode;
			curNode = curNode->next;
		}
		if(curNode->next == NULL)
			list->tailNode = preNode;
		preNode->next = curNode->next;
	}
	free(curNode);
	curNode = NULL;
	list->listSize--;
}

//查找
LPNODE searchNodeByData(LPLIST list, int posData) {
	LPNODE curNode = list->frontNode;
	while (curNode != NULL && curNode->data != posData) {
		curNode = curNode->next;
	}
	return curNode;
}
void deleteAllAppointData(LPLIST list, int posData) {
	while (searchNodeByData(list,posData) != NULL) {
		deleteByAppoint(list, posData);
	}
}
//打印
void printList(LPLIST list) {
	LPNODE curNode = list->frontNode;
	while (curNode != NULL) {
		printf("%d\t", curNode->data);
		curNode = curNode->next;
	}
	printf("\n");
}

//销毁链表
void destroyList(LPLIST* pList) {
	if (*pList != NULL) {
		for (int i = 0; i < (*pList)->listSize; i++) {
			deleteByHead(*pList);
		}
		free(*pList);
		*pList = NULL;
	}
}

int main()
{
	LPLIST list = createList();

	//头插
	for (int i = 0; i < 5; i++)
	{
		insertByHead(list, 520 + i);
		insertByHead(list, 520 + i);
	}
	printList(list);

	//尾插
	insertByTail(list, 100);
	printList(list);

	//指定位置插入
	insertByAppoint(list, 1001, 2);
	printList(list);

	//头删
	deleteByHead(list);
	printList(list);

	//尾删
	deleteByTail(list);
	printList(list);

	//指定数据删除
	deleteByAppoint(list, 1001);
	printList(list);

	//全部删除
	deleteAllAppointData(list, 522);
	printList(list);

	if (list != NULL) {
		printf("链表未销毁!\n");
	}
	//链表销毁
	destroyList(&list);
	if (list == NULL) {
		printf("链表已销毁!\n");
	}

	system("pause");
	return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,以下是Java语言实现一个无头链表的代码: ```java public class ListNode { int val; ListNode next; public ListNode(int val) { this.val = val; this.next = null; } } public class LinkedList { ListNode head; public LinkedList() { this.head = null; } public void add(int val) { ListNode newNode = new ListNode(val); if (head == null) { head = newNode; } else { ListNode cur = head; while (cur.next != null) { cur = cur.next; } cur.next = newNode; } } public void printList() { ListNode cur = head; while (cur != null) { System.out.print(cur.val + " "); cur = cur.next; } System.out.println(); } } ``` 代码解释: 首先定义一个 ListNode 类,表示链表中的每个节点,包含一个整数值 val 和指向下一个节点的指针 next。 然后定义一个 LinkedList 类,表示无头链表,包含一个头结点 head,初始值为 null。 在 LinkedList 类中,定义一个 add 方法,用于在链表尾部添加新元素。如果链表为空,直接将新元素作为头结点;否则,遍历链表,找到最后一个节点并将新元素插入其 next 指针所指的位置。 最后,定义一个 printList 方法,用于遍历链表并打印每个节点的值。 使用示例: ```java LinkedList list = new LinkedList(); list.add(1); list.add(2); list.add(3); list.printList(); // 输出:1 2 3 ``` 注意,这是一个简单的无头链表实现,只包含了添加元素和遍历链表的基本操作。在实际应用中,需要根据具体需求进行扩展和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

石小浪♪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值