要实现链表的基本操作,首先要了解链表的存储方式。
在链表中,首先要有一个head指针,指向这个链表的第一个元素,head指针用来维护,读取这个链表。链表的末尾指向NULL,用来表示链表的结束位置。
链表的简单操作有:
LinkList.h
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node* next;
}Node, *pNode, *pList;
void InitLinkList(pList* pplist); //二级指针 初始化
void PushFront(pList* pplist, DataType d); //头部插入
void Display(pList pl);//打印
void PushBack(pList* pplist, DataType d); //尾部插入
void PopBack(pList* pplist); //尾部删除
void PopFront(pList* pplist); //头部删除
int Find(pList* pplist, DataType d); //查找
void Insert(pList* pplist,DataType pos, DataType d); //位置插入
void Remove(pList* pplist, DataType d); //删除第一个查找到的节点
void RemoveAll(pList *pplist, DataType d); //删除有相同节点
#endif //__LINKLIST_H__
实现:
LinkList.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include "LinkList.h"
void Display(pList plist) //打印
{
assert(plist);
Node* cur=plist;
while (cur != NULL)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
void InitLinkList(pList* pplist) //初始化
{
*pplist = NULL;
}
void PushFront(pList* pplist, DataType d) // 头部插入 pplist来维护
{
Node*cur = NULL;
assert(pplist);
cur = (Node*)malloc(sizeof(Node));
if (cur == NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}
cur->data = d;
cur->next = NULL;
if (*pplist == NULL) //没有节点时
{
*pplist = cur;
}
else //有一个节点以上时
{
cur->next = *pplist;
*pplist = cur;
}
}
void PopFront(pList* pplist) //头部删除
{
assert(pplist);
if (*pplist==NULL)
{
perror("null");
exit(EXIT_FAILURE);
}
//头部有一个或者多个方法相同
Node *cur = *pplist;
Node *head = *pplist;
*pplist = head->next;
free(cur);
cur = NULL;
}
int Find(pList* pplist, DataType d) //查找
{
assert(pplist);
Node *cur = *pplist;
int pos = 0;
while (cur != NULL)
{
if (cur->data == d)
{
return pos;
}
pos++;
cur = cur->next;
}
return -1;
}
void Insert(pList* pplist, DataType pos, DataType d) //位置插入
{
int i = 0;
assert(pplist);
Node*pp = *pplist;
if (*pplist == NULL)
{
perror("null");
exit(EXIT_FAILURE);
}
if (pos == 0)
{
PushFront(pplist, d);
}
else
{
Node*cur = NULL;
cur = (Node*)malloc(sizeof(Node));
cur->data = d;
cur->next = NULL;
for (i = 0; i < pos-1; i++)
{
if (pp->next == NULL) //判断是否在末尾处
{
pp->next = cur;
return;
}
pp = pp->next;
}
cur->next = pp->next;
pp->next = cur;
}
}
void PushBack(pList* pplist, DataType d) //尾部插入
{
Node *pp = *pplist;
Node*cur = NULL;
cur = (Node*)malloc(sizeof(Node));
cur->data = d;
cur->next = NULL;
while (pp->next != NULL)
{
pp = pp->next;
}
pp->next = cur;
}
void PopBack(pList* pplist) //尾部删除
{
assert(pplist);
if (*pplist == NULL)
{
perror("null");
exit(EXIT_FAILURE);
}
Node *pp = *pplist;
while (pp->next->next != NULL)
{
pp = pp->next;
}
free(pp->next);
pp->next = NULL;
}
void Remove(pList* pplist, DataType d) //删除节点
{
assert(pplist);
int i = 0;
Node * pp = *pplist;
Node *cur = *pplist;
if (*pplist == NULL)
{
perror("null");
exit(EXIT_FAILURE);
}
int pos = Find(pplist, d);
if (pos == -1)
{
printf("查无此数");
return;
}
if (pos == 0) //等同于头部删除
{
PopFront(pplist);
}
else
{
for (i = 0; i < pos - 1; i++) //异位 pp用来维护 cur用来释放 pp提前一位停止
{
pp = pp->next;
}
for (i = 0; i < pos; i++)
{
cur = cur->next;
}
if (pp->next == NULL)
{
PopBack(pplist);
}
else
{
pp->next = pp->next->next;
free(cur);
cur = NULL;
}
}
}
void RemoveAll(pList *pplist, DataType d) //删除所有相同节点
{
assert(pplist);
if (*pplist == NULL)
{
perror("null");
exit(EXIT_FAILURE);
}
int ret = Find(pplist,d);
while (ret >= 0)
{
Remove(pplist, d);
ret = Find(pplist,d);
}
}
有点简单,就不测试了。