单链表基本操作实现——详解

      单链表是数据结构中十分常见,许多互联网公司笔试面试题好多都是单链表延伸出的,因此实能现一个单链表的基本操作很有必要,而且能让它不出现Bug还需要更细心。


基本功能:

1.添加元素            2.头插元素           

3.尾插元素            4.头删元素

5.尾删元素            6.销毁链表           

7.删除指定元素      8.指定位置插入元素


代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<Windows.h>
#include<assert.h>
typedef int DataType;
typedef struct Slist
{
	struct Slist *next;
	DataType data;
}Slist;


Slist List;



Slist *BuySlist(DataType x)		//添加元素
{
	Slist *node = (Slist *)malloc(sizeof(Slist));
	assert(node);
	node->data = x;
	node->next = NULL;
	return node;
}


void ListPushback(Slist **head, DataType x)		//尾插元素
{
	if (*head == NULL)		//没有元素的情况
	{
		*head = BuySlist(x);
	}
	else
	{
		Slist *cur = *head;
		while (cur->next != NULL)
		{		
			cur = cur->next;
		}
		cur->next = BuySlist(x);
	}
}



void ListPopBack(Slist **head)		//尾删元素
{
	if (*head == NULL)		//没有元素
	{
		return;
	}
	else if ((*head)->next == NULL)		//只有一个元素
	{
		free(*head);
		*head = NULL;		//防止内存泄漏
	}
	Slist *cur = *head;
	Slist *pos = cur;
	while (cur->next != NULL)
	{
		pos = cur;		//上下位置不能变
		cur = cur->next;		
	}
	free(cur);
	cur = NULL;
	pos->next = NULL;		//此时pos为尾结点
}

void ListPushFront(Slist **head, DataType x)		//头插元素
{
	if (*head == NULL)		//没有结点
	{
		*head = BuySlist(x);
		return;
	}
	Slist *new;
	new = BuySlist(x);
	new->next = *head;
	*head = new;
}

void ListPopFront(Slist **head)//头删元素
{
	if (*head==NULL)
	{
		return;
	}
	//else if ((*head)->next == NULL)//一个节点		//注意这里不能写成*head->next,这是错的,存在优先级问题
	//{
	//	free(*head);
	//	*head = NULL;
	//}
	Slist *cur = (*head)->next;
	free(*head);
	*head = cur;
}


void ListDestory(Slist **head)		//销毁单链表
{
	Slist *cur = *head;
	while (cur)
	{
		Slist *next = cur->next;
		free(cur);
		cur = next;
	}
	*head = NULL;
}

Slist *Find(Slist *head, DataType x)		//查找指定元素,返回下标
{
	Slist *cur = head;
	while (cur!=NULL)
	{
		if (cur->data == x)
		{
			return cur;

		}
		cur = cur->next;
	}
	return NULL;
}



void ListErase(Slist **head, Slist *pos)		//删除任意节点
{
	assert(pos&&*head);
	if ((*head) == pos)		//删除头节点
	{
		ListPopFront(head);
	}
	else if (pos->next == NULL)		//删除尾节点
	{
		ListPopBack(head);
	}
	else
	{
		Slist *prev = *head;

		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev = pos->next;
		free(pos);
	}
}

void Insert(Slist **head, Slist *pos, DataType x)		//插入元素
{
	assert(*head&&pos);
	Slist *cur = *head;
	Slist *tmp=NULL;
	while (cur->next!=pos)
	{
		
		cur=cur->next; 
	}
	/*tmp->data = x;
	tmp->next = pos;*/
	tmp = BuySlist(x);
	tmp->next = pos;
	cur->next = tmp;
}

void print(Slist *head)			//打印元素
{
	Slist *cur = head;
	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL");
	printf("\n");
}


void test1(Slist *list)
{
	list = NULL;
	ListPushback(&list, 1);		//不能传list,实际上传的是地址的值,要传二级指针
	ListPushback(&list, 7);
	ListPushback(&list, 4);
	ListPushback(&list, 15);
	ListPushFront(&list, 10);
	Slist *pos = Find(list, 7);
	Insert(&list, pos, 2);
	//ListPopFront(&list);
	//ListPopBack(&list);
	print(list);
}

int main()
{	
	test1(&List);
	system("pause");
	return 0;
}

test函数根据自己的使用情况来调用任意函数





猜你喜欢

转载自blog.csdn.net/yc1515707718/article/details/79748449