无头链表(完整版)

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct Node 
{
	int data;
	struct Node* next;
};

struct Node* createNode(int data) 
{
	struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
	assert(newNode);
	newNode->data = data;
	newNode->next = NULL;
	return newNode;
}

//无头链表有两种写法
//No.1 简单写法: 再封装法
//1.1 一个指针(表头)
//1.2 两个指针(记录表头表尾的方式)
struct List 
{
	struct Node* headNode;		//指向链表的第一个节点,表示整个链表
	struct Node* tailNode;		//永远指向最后一节点
	int listSize;				//大多数数据结构中都有的一个属性(当前数据结构中的元素个数) 万金油参数
};

struct List* createList() 
{
	struct List* list = (struct List*)malloc(sizeof(struct List));
	assert(list);
	list->listSize = 0;
	list->headNode = NULL;
	list->tailNode = NULL;
	return list;
}
void insertByHead(struct List* list,int data) 
{
	struct Node* newNode = createNode(data);
	if (list->listSize == 0) 
	{
		list->tailNode = newNode;
		//list->headNode = newNode;
		//list->listSize++;
	}
	else 
	{
		newNode->next = list->headNode;
		//list->headNode = newNode;
		//list->listSize++;
	}
	list->headNode = newNode;
	list->listSize++;
}
void insertByTail(struct List* list, int data) 
{
	struct Node* newNode = createNode(data);
	if (list->listSize == 0) 
	{
		list->headNode = newNode;
		//list->tailNode = newNode;
		//list->listSize++;
	}
	else 
	{
		list->tailNode->next = newNode;
		//list->tailNode = newNode;
		//list->listSize++;
	}
	list->tailNode = newNode;
	list->listSize++;
}
//指定插入: 唯一的问题是:  如果采用指定位置前面插入,要考虑表头插入
//data: 插入的数据
//posData: 插入的位置(参照点)
void insertAppoin(struct List* list, int data, int posData) 
{
	//对于查找,初始值赋值操作,是看你操作的时候判断是否顺利
	struct Node* posLeftNode = list->headNode;
	struct Node* posNode = list->headNode;
	while (posNode != NULL && posNode->data != posData) 
	{
		posLeftNode = posNode;
		posNode = posLeftNode->next;	//
		//posNode=posNode->next;
	}
	if (posNode == NULL) 
	{
		printf("无法插入!\n");
	}
	else if(posNode==list->headNode)
	{
		insertByHead(list, data);
	}
	else 
	{
		struct Node* newNode = createNode(data);
		posLeftNode->next = newNode;
		newNode->next = posNode;
		list->listSize++;
	}
}

//自己写删除
//删除相对于有头链表更难
//表头删除
void deleteHead(struct List* list) 
{
	if (list->listSize == 0) 
	{
		printf("无法删除!\n");
	}
	else 
	{
		struct Node* nextNode = list->headNode->next;  //NULL
		free(list->headNode);
		list->headNode = nextNode; //NULL
		if (list->listSize == 1)   //nextNode==NULL  list->headNode==NULL 
			list->tailNode = NULL;
		list->listSize--;
	}
}
//表尾删除
//指定删除
void printList(struct List* list) 
{
	struct Node* pMove = list->headNode;
	while (pMove != NULL) 
	{
		printf("%d\t", pMove->data);
		pMove = pMove->next;
	}
	printf("\n");
}


//No.2 二级指针写法
int main() 
{
	struct List* list = createList();
	for (int i = 0; i < 3; i++)			//2 1 0
	{
		insertByHead(list, i);
	}
	for (int i = 0; i < 3; i++)  //2 1 0 0 1 2
	{
		insertByTail(list, i);
	}
	printList(list);
	insertAppoin(list, 100, 0);
	printList(list);
	insertAppoin(list, 100, 2);
	printList(list);
	struct List* mylist = createList();
	insertByHead(mylist, 1);
	printList(mylist);
	deleteHead(mylist);
	printList(mylist);
	insertByTail(mylist,2);
	printList(mylist);


	return 0;
}
当我们需要在单向无头链表中查找某个元素时,我们需要遍历整个链表,直到找到目标元素或者链表结束。下面是一个示例的单向无头链表查找代码: ```c++ #include <iostream> // 定义链表节点结构 struct Node { int data; // 节点数据 Node* next; // 指向下一个节点的指针 }; // 在链表尾部插入新节点 void insert(Node** head, int data) { Node* newNode = new Node(); // 创建新节点 newNode->data = data; newNode->next = nullptr; if (*head == nullptr) { *head = newNode; } else { Node* currNode = *head; while (currNode->next != nullptr) { currNode = currNode->next; } currNode->next = newNode; } } // 在链表中查找目标元素 bool search(Node* head, int target) { Node* currNode = head; while (currNode != nullptr) { if (currNode->data == target) { return true; } currNode = currNode->next; } return false; } // 打印链表元素 void display(Node* head) { Node* currNode = head; while (currNode != nullptr) { std::cout << currNode->data << " "; currNode = currNode->next; } std::cout << std::endl; } int main() { Node* head = nullptr; // 插入节点 insert(&head, 1); insert(&head, 2); insert(&head, 3); insert(&head, 4); // 打印链表 display(head); // 查找元素 int target = 3; if (search(head, target)) { std::cout << target << " found in the list." << std::endl; } else { std::cout << target << " not found in the list." << std::endl; } return 0; } ``` 在上面的代码中,我们定义了一个 `Node` 结构表示链表的节点,其中 `data` 存储节点的数据,`next` 指向下一个节点。`insert` 函数用于在链表尾部插入新节点。`search` 函数用于在链表中查找目标元素,并返回是否找到。`display` 函数用于打印链表的所有元素。 在 `main` 函数中,我们创建一个空链表,并插入一些节点。然后,我们调用 `display` 函数打印链表,再调用 `search` 函数查找目标元素是否存在。最后输出结果。 注意:这只是一个简单的示例代码,实际应用中可能需要处理更多的边界情况和错误处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值