单向链表的操作

has_head_list.h

#ifndef _HAS_HEAD_LIST_H_
#define _HAS_HEAD_LIST_H_

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define DEBUG(format, ...) \
do { \
printf("[DEBUG][%s:%d][%s:%s]"format, __FUNCTION__, __LINE__, __DATE__, __TIME__, ##__VA_ARGS__); \
} while (0)

#define ERROR(format, ...) \
do { \
printf("[ERROR][%s:%d][%s:%s]"format, __FUNCTION__, __LINE__, __DATE__, __TIME__, ##__VA_ARGS__); \
} while (0)

struct node
{
	int data;
	struct node *next;
};


//初始化一个链表
void init_list(struct node **head_p);

//创建一个节点
struct node *make_node(int data);

//释放一个节点
void free_node(struct node *node);

//插入一个节点(头)
int insert_node_from_begin(struct node *head, struct node* node);


//插入一个节点(尾)
int insert_node_to_end(struct node *head, struct node* node);

//查找一个节点
struct node *search(struct node *head, int data);

//删除一个节点
int delete_node(struct node *head, struct node *del_node);

//销毁整个链表
void destory_list(struct node **head_p);

//遍历链表
void print_list(struct node *head);

//逆序单向链表
int reverse(struct node *head);

void print_node(struct node *node); //void ()(struct node *)

void add_node(struct node *node);

void for_each(struct node *head, void(*fp)(struct node*));





#endif

has_head_list.c

#include "has_head_list.h"


void init_list(struct node **head_p)
{
	struct node *head = NULL;

	if (head_p == NULL) {
		return;
	}

	head = (struct node *)malloc(sizeof(struct node));
	if (head == NULL) {
		return;
	}

	head->data = -1; //无意义
	head->next = NULL;//代表是空链表


	*head_p = head;
}

struct node *make_node(int data)
{
	struct node *new_node = NULL;

	new_node = (struct node *)malloc(sizeof(struct node));
	if (new_node == NULL) {
		ERROR("new node == NULL\n");
		return NULL;
	}
	new_node->data = data;
	new_node->next = NULL;

	return new_node;
}

//释放一个节点
void free_node(struct node *node)
{
	if (node != NULL) {
		free(node);
	}
}

//插入一个节点(尾)
int insert_node_to_end(struct node *head, struct node* node)
{
	struct node* last_node = NULL;

	if (head == NULL || node == NULL) {
		return -1;
	}

	//找到last_node
	for (last_node = head; last_node->next != NULL; last_node = last_node->next)
	{

	}

	//让最后一个节点的下一个指针 指向 node就可以了
	last_node->next = node;


	node->next = NULL;

	return 0;
}



//插入一个节点(头)
int insert_node_from_begin(struct node *head, struct node* node)
{

	if (head == NULL || node == NULL) {
		return -1;
	}

	//让新节点的下一个的方向 跟head->next一样
	node->next = head->next;
	head->next = node;

	return 0;
}


//销毁整个链表
void destory_list(struct node **head_p)
{
	struct node *head = NULL;
	struct node *p = NULL;

	if (head_p == NULL) {
		return;
	}

	head = *head_p;

	//删除所有链表元素
	for (p = head->next; p != NULL;  ) {
		head->next = p->next;
		free_node(p);
		p = head->next;
	}

	//删除头结点本身
	free_node(head);
	*head_p = NULL;
}

//查找一个节点
struct node *search(struct node *head, int data)
{
	struct node *p = NULL;

	if (head == NULL) {
		return NULL;
	}

	for (p = head->next; p != NULL; p = p->next)
	{
		if (p->data == data) {
			//找到了data与之对应的节点 此时p就是这个节点的地址
			return p;
		}
	}

	return NULL;
}

//删除一个节点
int delete_node(struct node *head, struct node *del_node)
{
	struct node*p = NULL;

	if (head == NULL || del_node == NULL) {
		return -1;
	}


	//由于要通过p能够指向元素的前驱, 所以p应该从head开始遍历, 因为首元素的前驱就是head
	for (p = head; p->next != NULL; p = p->next) {
		if (p->next == del_node) {
			//此时找到了del_node的前驱节点,就是p
			p->next = del_node->next;
			free_node(del_node);
			break;
		}
	}


	return 0;
}

//逆序单向链表
int reverse(struct node *head)
{
	struct node *p = NULL;
	struct node *p_prev = NULL;//p的前驱节点
	struct node *p_next = NULL;//p的后继节点


	if (head == NULL) {
		//printf("head is NULL %s:%d\n", __FUNCTION__, __LINE__);
		ERROR("head is NULL\n");
		return -1;
	}

	//对空链表的处理
	if (head->next == NULL) {
		return 0;
	}

	p = head->next;//p一开始应该指向首元素
	p_prev = head;//首元素的前驱就是head
	
	while (p != NULL) {
		//给出p的后继
		p_next = p->next;

		//将p的next指向p的前驱
		p->next = p_prev;

		//让p的前驱 指向p本身,称为下一个p的前驱
		p_prev = p;

		//p指向p的后继
		p = p_next;
	}

	//将原先的首元素的next 指向null
	head->next->next = NULL;

	//head->next指向新的首元素 此时就是p_prev
	head->next = p_prev;



	return 0;
}

//遍历链表
void print_list(struct node *head)
{
	struct  node * p = NULL;

	if (head == NULL) {
		return;
	}


	for (p = head->next; p != NULL; p = p->next)
	{
		//printf("%d\n", p->data);
		DEBUG("%d\n", p->data);
	}
}


//打印一个节点
void print_node(struct node *node) //void ()(struct node *)
{
	//printf("%d\n", node->data);
	DEBUG("%d\n", node->data);
}

//给一个节点的数值自增1
void add_node(struct node *node)
{
	node->data += 1;
}


//
void for_each(struct node *head, void(*fp)(struct node*))
{
	struct node *p;

	for (p = head->next; p != NULL; p = p->next) {
		//P 就代表一个节点
		fp(p);
	}
}

main.c


#define  _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "has_head_list.h"

int main(int argc, char **argv)
{
	struct node *head = NULL;
	struct node *new_node = NULL;
	struct node *del_node = NULL;

	int data = 0;
	int num = 10;
	int i = 0;

	//有头链表 head应该有自己的内存空间
	init_list(&head); //head->next = NULL;

	for (i = 0; i < num; i++) {
		new_node = make_node(i + 10);
		//insert_node_to_end(head, new_node);
		insert_node_from_begin(head, new_node);
	}

	//遍历
	print_list(head);


	printf("请输入要删除的节点:");
	scanf("%d", &data);

	del_node = search(head, data);
	if (del_node != NULL) {
		delete_node(head, del_node);
	}


	//printf("%d\n", strlen("abc"));

	printf("----\n");

	reverse(head);

	//print_list(head);
	for_each(head, print_node);

	for_each(head, add_node);

	for_each(head, print_node);


	//销毁链表
	destory_list(&head);

	if (head == NULL) {
		printf("销毁链表成功\n");
	}


	return 0;
}


















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是单向链表的基本操作的实现(代码使用C语言): ```c #include <stdio.h> #include <stdlib.h> // 定义链表节点结构体 typedef struct Node { int data; // 数据 struct Node *next; // 指向下一个节点的指针 } Node; // 创建链表 Node *createList() { Node *head = (Node*)malloc(sizeof(Node)); // 创建头节点 head->next = NULL; // 头节点的指针指向NULL return head; } // 在链表尾部插入节点 void insertAtTail(Node *head, int data) { Node *newNode = (Node*)malloc(sizeof(Node)); // 创建新节点 newNode->data = data; // 设置新节点数据 newNode->next = NULL; // 新节点的指针指向NULL Node *p = head; while (p->next != NULL) { // 找到链表尾部 p = p->next; } p->next = newNode; // 将新节点连接到尾部 } // 在链表头部插入节点 void insertAtHead(Node *head, int data) { Node *newNode = (Node*)malloc(sizeof(Node)); // 创建新节点 newNode->data = data; // 设置新节点数据 newNode->next = head->next; // 新节点的指针指向头节点的下一个节点 head->next = newNode; // 头节点的指针指向新节点 } // 删除指定位置的节点 void deleteNode(Node *head, int pos) { Node *p = head; int i = 0; while (p->next != NULL && i < pos-1) { // 找到要删除的节点的前一个节点 p = p->next; i++; } if (p->next == NULL || i > pos-1) { // 如果要删除的位置不存在,则直接返回 printf("Position does not exist!\n"); return; } Node *temp = p->next; // 保存要删除的节点 p->next = temp->next; // 将要删除的节点从链表中断开 free(temp); // 释放要删除的节点的空间 } // 打印链表 void printList(Node *head) { Node *p = head->next; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); } int main() { Node *head = createList(); // 创建链表 insertAtTail(head, 1); // 在尾部插入1 insertAtTail(head, 2); // 在尾部插入2 insertAtTail(head, 3); // 在尾部插入3 insertAtHead(head, 0); // 在头部插入0 printList(head); // 打印链表:0 1 2 3 deleteNode(head, 2); // 删除位置2的节点 printList(head); // 打印链表:0 1 3 return 0; } ``` 这份代码实现了链表的基本操作:创建链表、在尾部插入节点、在头部插入节点、删除指定位置的节点和打印链表。你可以根据需要进行修改和扩展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值