单链表的基本操作

单链表的基本操作

1、头文件(list.h)
#pragma once
//带头节点的单链表,尾节点的next为NULL
//头节点起哨兵位作用,它不使用(数据域不能存储数据)

typedef struct Node
{
	int data;//保存数据
	struct Node *next;//保存下一节点的地址
}Node,*List;//List == Node*

//typedef struct Node *List;

//链表初始化
void InitList(List plist);

//头插
bool Insert_head(List plist,int val);

//尾插
bool Insert_tail(List plist,int val);

//查找
Node *Search(List plist,int key);

//删除
bool Delete(List plist,int key);

//获取单链表的长度
int GetLength(List plist);

//判空
bool IsEmpty(List plist);

//清空
void Clear(List plist);

//摧毁
void Destroy(List plist);

//打印
void Show(List plist);

//获取元素
bool GetElem(List plist,int pos,int *rtval);

//逆置
void Reverse(List plist);//考试的重点内容

//除去重复的数据值
void Unique(List plist);



2、源文件
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"list.h"

//链表初始化
void InitList(List plist)
{
	assert(plist != NULL);
	if(plist == NULL)
	{
		return ;
	}

	plist->next = NULL;
}

//头插 时间复杂度O(1)
bool Insert_head(List plist,int val)
{
	assert(plist != NULL);
	if(plist == NULL)
	{
		return false;
	}

	Node *p = (Node *)malloc(sizeof(Node));
	p->data = val;
	p->next = plist->next;
	plist->next = p;

	return true;
}

//尾插
bool Insert_tail(List plist,int val)
{

	Node *p = (Node *)malloc(sizeof(Node *));
	p->data = val;

	Node *q;
	for(q = plist;q->next != NULL;q = q->next);

	q->next = p;
	p->next = NULL;

	return true;
} 

//查找
Node *Search(List plist,int key)
{
	assert(plist != NULL);
	if(plist == NULL)
	{
		return false;
	}

	for(Node *p = plist->next;p != NULL;p = p->next)
	{
		if(p->data == key)
		{
			return p;
		}
	}
	return NULL;
}

//删除
bool Delete(List plist,int key)
{
	Node *p;
	for(p = plist;p->next != NULL;p = p->next)
	{
		if(p->next->data == key)
		{
			Node *q = p->next;//记录即将要删除的结点
			p->next = q->next;
			free(q);

			return true;
		}
	}
	return false;
}

//获取单链表的长度
int GetLength(List plist)
{
	int count = 0;
	for(Node *p = plist->next;p != NULL;p = p->next)
	{
		count++;
	}
	return count;
}

//判空
bool IsEmpty(List plist)
{
	return plist->next == NULL;
}

//清空
void Clear(List plist)
{
	Destroy(plist);
}

//摧毁
void Destroy(List plist)
{
	Node *p;
	while(plist->next != NULL)
	{
		p = plist->next;
		plist->next = p->next;
		free(p);
	}
}

//打印
void Show(List plist)
{
	for(Node *p = plist->next;p != NULL;p = p->next)
	{
		printf("%d ",p->data);
	}
	printf("\n");
}

//获取元素
bool GetElem(List plist,int pos,int *rtval)
{
	if(pos < 0 || pos >= GetLength(plist))
	{
		return false;
	}

	int i = 0;
	for(Node *p = plist->next;p != NULL;p= p->next)
	{
		if(i == pos)
		{
			*rtval = p->data;
			return true;
		}
		i++;
	}

	return false;
}

//得到结点p的前驱
static Node *GetPri(List plist,Node *p)
{
	for(Node *q=plist;q->next !=NULL ;q=q->next)
	{
		if(q->next == p)
		{
			return q;
		}
	}

	return NULL;
}

//逆置
void Reverse(List plist)//考试的重点内容
{
	if(plist == NULL || plist->next == NULL || plist->next->next == NULL)
	{
		return ;
	}

	//时间复杂度为O(n),并且最好,利用了头插法的思想
	Node *p = plist->next;
	Node *q;
	plist->next = NULL;

	while(p != NULL)
	{
		q = p->next;

		p->next = plist->next;
		plist->next = p;

		p = q;
	}

	/*
	//时间复杂度为O(n^2)
	Node *p = plist->next;
	Node *q;
	int tmp;

	for(q = plist;q->next != NULL;q = q->next);
	
	for(int i = 0;i < GetLength(plist)/2;i++)
	{
		tmp = p->data;
		p->data = q->data;
		q->data = tmp;

		p = p->next;
		q= GetPri(plist,q);
	}*/

}
//除去重复的数据值
void Unique(List plist)
{
	Node *p;
	Node *q;

	for(p = plist->next;p != NULL;p = p->next)
	{
		for(q = p;q->next != NULL;q = q->next)
		{
			if(q->next->data == p->data)
			{
				Node *s = q->next;
				q->next = s->next;
				free(s);
			}
		}
	}
}



3、测试源文件

#include<stdio.h>
#include<vld.h>
#include"list.h"

int main()
{
	Node head1;
	Node head2;

	InitList(&head1);
	InitList(&head2);

	for(int i = 0;i < 15;i++)
	{
		Insert_head(&head1,i);
		Insert_tail(&head2,i);
	}

	Show(&head1);
	Show(&head2);

	Reverse(&head1);
	Show(&head1);

	int val;
	GetElem(&head2,3,&val);
	printf("%d\n",val);
	
	Destroy(&head1);
	Destroy(&head1);

	return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值