每天进步一点点!
单链表的我插入、删除、查找、、、
头文件声明:
#ifndef __LINKLIST__
#define __LINKLIST__
#include <stdio.h>
#include <windows.h>
#include <assert.h>
#pragma warning(disable:4996)
//实现无头单链表的如下操作
typedef int DataType;
typedef struct Node
{
struct Node* next;
DataType data;
}Node, *PNode;
/
// 初始化单链表---思考为什么要传递二级指针
void InitList(PNode* pHead);
// 在链表尾部插入值为data的新结点
void PushBack(PNode* pHead, DataType data);
// 删除链表的最后一个节点
void PopBack(PNode* pHead);
// 在链表头部插入置为data的新节点
void PushFront(PNode* pHead, DataType data);
// 删除链表的第一个结点
void PopFront(PNode* pHead);
// 查找链表中值为data的结点,存在返回该结点的地址,否则返回空
PNode Find(PNode pHead, DataType data);
//在链表pos位置后插入值为data的新节点
void Insert(PNode pos, DataType data);
// 删除单链表pos位置上的结点
void Erase(PNode* pHead, PNode pos);
// 移除链表中第一个值为data的结点
void Remove(PNode* pHead, DataType data);
// 移除链表中所有值为data的结点
void RemoveAll(PNode* pHead, DataType data);
// 获取链表中结点的总个数
size_t Size(PNode pHead);
// 获取链表中第一个结点
PNode Front(PNode pHead);
// 获取链表中最后一个节点
PNode Back(PNode pHead);
// 判断链表是否为空
int Empty(PNode pHead);
// 打印单链表
void PrintList(PNode pHead);
// 构建新节点
PNode BueNode(DataType data);
链表面试题
// 从尾到头打印单链表
void PrintListFromTail(PNode pHead);
// 删除无头单链表的非尾结点,要求:不能遍历单链表
void DelectNotTailNode(PNode* pHead, PNode pos);
// 在无头单链表非头结点前插入新节点
void InsertNotHeadNode(PNode pos, DataType data);
#endif
#include "LinkList.h"
///
// 初始化单链表---思考为什么要传递二级指针? //
//(使用一级指针,调用函数时形参压栈,函数结束时,/
// 形参会随之释放,期间对其参数的所有操作都无效。//
///
//初始化单链表
void InitList(PNode* pHead)
{
assert(pHead);
*pHead = NULL;
}
// 构建新节点
PNode BuyNode(DataType data)
{
//申请内存
PNode pNewNode = (PNode)malloc(sizeof(Node));
if(NULL == pNewNode){
perror("malloc");
exit(1);
}
pNewNode->data = data;
pNewNode->next = NULL;
return pNewNode;
}
// 在链表尾部插入值为data的新结点
void PushBack(PNode* pHead, DataType data)
{
PNode pCur = *pHead;
assert(pHead);
//链表为空则直接插入
if(NULL == *pHead){
*pHead = BuyNode(data);
}
else{
//否则寻找尾节点
while(pCur->next){
pCur = pCur->next;
}
//插入
pCur->next = BuyNode(data);
}
}
// 删除链表的最后一个节点
void PopBack(PNode* pHead)
{
PNode pCur = *pHead;
PNode pTail = NULL;
assert(pHead);
//若链表为空则返回
if(NULL == *pHead){
return ;
}
//若只有一个节点
else if(NULL == (*pHead)->next){
free(*pHead);
*pHead = NULL;
}
else{
//节点个数大于一
//寻找倒数第二个节点
while(pCur->next->next){
pCur = pCur->next;
}
pTail = pCur->next;//记录尾节点
free(pTail);//释放尾节点
pCur->next =NULL;
}
}
// 在链表头部插入置为data的新节点
void PushFront(PNode* pHead, DataType data)
{
PNode pNewHead = BuyNode(data);
pNewHead->next = *pHead;
*pHead = pNewHead;
}
// 删除链表的第一个结点//
void PopFront(PNode* pHead)
{
PNode pDelNode = NULL;
assert(pHead);
if(NULL == *pHead){
return ;
}
else{
pDelNode = *pHead;
*pHead = (*pHead)->next;
free(pDelNode);
}
}
// 查找链表中值为data的结点,存在返回该结点的地址,否则返回空
PNode Find(PNode pHead, DataType data)
{
PNode pCur = pHead;
//遍历查找
while(pCur){
if(data == pCur->data){
return pCur;
}
pCur = pCur->next;
}
return NULL;
}
//在链表pos位置后插入值为data的新节点
void Insert(PNode pos, DataType data)
{
PNode pNewNode = NULL;
if(NULL == pos){
return ;
}
pNewNode = BuyNode(data);
pNewNode->next = pos->next;
pos->next = pNewNode;
}
// 删除单链表pos位置上的结点
void Erase(PNode* pHead, PNode pos)
{
PNode pPreNode = NULL;
assert(pHead);
if(NULL == *pHead || NULL == pos){
return ;
}
//若待删节点为头结点则特殊处理
if(pos == *pHead){
(*pHead) = pos->next;
free(pos);
}
//找到待删节点的下一个节点
else{
pPreNode = *pHead;
while(pos != pPreNode->next){
pPreNode = pPreNode->next;
}
pPreNode->next = pos->next;
free(pos);
}
}
// 移除链表中第一个值为data的结点
void Remove(PNode* pHead, DataType data)
{
assert(pHead);
Erase(pHead, Find(*pHead, data));
}
// 移除链表中所有值为data的结点
void RemoveAll(PNode* pHead, DataType data)
{
PNode pDelNode = NULL;
PNode pPreNode = NULL;
pPreNode = *pHead;
pDelNode = (*pHead)->next;
assert(pHead);
//先从第二个节点开始处理
while(pDelNode){
if(pDelNode->data == data){
pPreNode->next = pDelNode->next;
free(pDelNode);
pDelNode = pPreNode;
}
pPreNode = pDelNode;
pDelNode = pDelNode->next;
}
//结束后再处理第一个节点
if((*pHead)->data == data){
pDelNode = *pHead;
*pHead = pDelNode->next;
free(pDelNode);
}
}
// 获取链表中结点的总个数
size_t Size(PNode pHead)
{
size_t num = 0;
PNode pCur = pHead;
while(pCur){
num++;
pCur = pCur->next;
}
return num;
}
// 获取链表中第一个结点
PNode Front(PNode pHead)
{
return pHead;
}
// 获取链表中最后一个节点
PNode Back(PNode pHead)
{
PNode pCur = pHead;
//若为空直接返回
if(NULL == pHead){
return NULL;
}
//不空则遍历
else{
while(pCur->next)
{
pCur = pCur->next;
}
return pCur;
}
}
// 判断链表是否为空
int Empty(PNode pHead)
{
if(NULL == pHead){
return 1;
}
else{
return 0;
}
}
// 打印单链表
void PrintList(PNode pHead)
{
PNode pCur = pHead;
while(pCur){
printf("%d->", pCur->data);
pCur = pCur->next;
}
printf("NULL\n");
}
链表面题///
//逆序打印
void PrintListFromTail(PNode pHead)
{
//递归
if(pHead->next){
PrintListFromTail(pHead->next);
}
printf("%d->", pHead->data);
}
//删除非尾节点
void DelectNotTailNode(PNode* pHead, PNode pos)
{
PNode posNextNode = NULL;
if(NULL == pos || NULL == pos->next){
return;
}
//将待删节点后一个节点data域赋给待删节点,再删除后面的节点
posNextNode = pos->next;
pos->data = posNextNode->data;
pos->next = posNextNode->next;
free(posNextNode);
}
//在非头节点前插入
void InsertNotHeadNode(PNode pos, DataType data)
{
PNode pNewNode = NULL;
if(NULL == pos){
return ;
}
//插到该节点的后面,再将该节点与其交换
pNewNode = BuyNode(pos->data);
pNewNode->next = pos->next;
pos->next = pNewNode;
pos->data = data;
}
成于坚持,败于止步!