注意:
- 表头和头结点的区别,个人理解表头的元素因为没用到所以可不初始化
- 清空链表是仍保留链表的头结点,此时L!= NULL;而销毁链表是整个链表为空,L==NULL
- 表头指针和链表指针同时指向链表所在的内存,使用时要注意,尤其delete时。
可直接在vs2015上运行
#include <iostream>
using namespace std;
typedef struct Node
{
int Element;
Node* Next;
}*Position, *SearchList, *Head;
SearchList MakeEmpty(SearchList L);
bool IsEmpty(SearchList L);
bool IsLast(Position L);
Position Find(int x, SearchList L);
Position FindPrevious(int x, SearchList L);//查找x的前驱
void DeleteNode(int x, SearchList L);
void InsertNode(int x, SearchList L);//前插
SearchList CreatList();//利用输入创建链表
void Traverse(SearchList L);
//清空链表,但仍保留头结点
SearchList MakeEmpty(SearchList L)
{
//从第一个节点开始删除
if (L == NULL)
return NULL;
Head pHead = L;
L = pHead->Next;//第一个结点
while (pHead->Next != NULL)
{
Position pTmp = new Node;
pTmp = L;
pHead->Next = pTmp->Next;
L = L->Next;
delete pTmp;//要最后delete,因为pTmp和L指向一个地址
}
return pHead;
}
bool IsEmpty(SearchList L)
{
if (L == NULL)
return true;
else
return false;
}
bool IsLast(Position L)
{
if (L->Next == NULL)
return true;
else
return false;
}
//返回x所在结点
Position Find(int x, SearchList L)
{
if (L->Next == NULL)//空链表,但表头可能存在
return nullptr;
Head pHead = L;
L = L->Next;
while (L != NULL && L->Element != x)//顺序不能乱
L = L->Next;
return L;
}
Position FindPrevious(int x, SearchList L)
{
if (L->Next == NULL)//空链表,但表头可能存在
return nullptr;
Head pHead = L;
//L = L->Next;//第一个结点
Position pTmp = nullptr;
pTmp = new Node;
pTmp = pHead;
while (L->Next != NULL && L->Next->Element != x)
{
pTmp = L;
L = L->Next;
}
if (L == NULL)
return nullptr;
return pTmp;
}
void DeleteNode(int x, SearchList L)
{
Position xPre = FindPrevious(x, L);
if (xPre)
{
Position xPos = xPre->Next;
if (xPos->Next != nullptr)
{
Position xNext = xPos->Next;
xPre->Next = xNext;
}
else
xPre->Next = nullptr;
}
else
cout << "没有要删除的元素,无需删除" << endl;
}
void InsertNode(int x, SearchList L)
{
Head pHead = L;
Position xPos = Find(x, L);
if (xPos == NULL)
{
Position pTmp = new Node;
pTmp->Element = x;
pTmp->Next = pHead->Next;
pHead->Next = pTmp;
L = pHead;
}
}
SearchList CreatList()
{
Head pHead = nullptr;
pHead = new Node;//表头
SearchList L = pHead;
L->Next = nullptr;//带表头的空链表
cout << "Input data(-999 to quit):" << endl;
int val = 0;
while (1)
{
cin >> val;
if (val == -999)
break;
Position isFind = Find(val, pHead);
if (isFind)//重复元素不处理
continue;
Position newCell = nullptr;
newCell = new Node;
newCell->Element = val;
newCell->Next = nullptr;
L->Next = newCell;
L = L->Next;//更新位置
}
return pHead;
}
void Traverse(SearchList L)
{
if (L == NULL)
cout << "链表为空" << endl;
L = L->Next;
while (L != NULL)
{
cout << L->Element << " ";
L = L->Next;
}
cout << endl;
}
int main()
{
char key;
int num = 0;
SearchList L = CreatList();
Traverse(L);
cout << "输入查找数字:";
cin >> num;
Position isFind = Find(num, L);
if (isFind)
cout << "查找成功,位置:" << isFind << endl;
else
cout << "未查找到" << endl;
cout << "输入删除的数字:";
cin >> num;
DeleteNode(num, L);
cout << "删除后的链表:" << endl;
Traverse(L);
cout << "输入插入的数字(重复不处理):";
cin >> num;
InsertNode(num, L);
cout << "插入后的链表:" << endl;
Traverse(L);
cout << "输入c让链表置空:" << endl;
cin >> key;
if (key == 'c' || key == 'C')
L = MakeEmpty(L);
if (IsEmpty(L))
cout << "置空成功" << endl;
system("pause");
}