11.单链表
1.链表结构
typedef struct _LinkNode
{
int data; //结点的数据域
struct _LinkNode* next; //结点的指针域
}LinkNode, LinkList; //LinkList 为指向结构体LNode 的指针类型
2.链表初始化
bool InitList(LinkList*& L)
{
L = new LinkNode;
if (!L) return false;//生成节点失败
L->next = NULL;
return true;
}
3.插入数据
3.1前插
//前插法
bool ListInsert_front(LinkList* &L, LinkNode *node)
{
if (!L || !node) return false;
node->next = L->next;
L->next = node;
}
3.2尾插
//尾插法
bool ListInsert_back(LinkList*& L, LinkNode* node)
{
LinkNode* last = NULL;
if (!L || !node) return false;
last = L;
while (last->next) last = last->next;
node->next = NULL;
last->next = node;
return true;
}
3.3任意位置插入元素
//指定位置插入元素
bool LinkInsert(LinkList*& L, int i, int& e)
{
if (!L) return false;
int j = 0;//当前位置
LinkList* p, *s;
p = L;
while (p && j < i - 1)//查找位置为i - 1的结点,p指向该结点
{
p = p->next;
j++;
}
if (!p || j > i - 1)//无效位置
{
return false;
}
s = new LinkNode;//生成新节点
s->data = e;
s->next = p->next;
p->next = s;
}
4.打印
//打印
void LinkPrint(LinkList*& L)
{
LinkNode* p = NULL;
if (!L)
{
cout << "链表为空。";
return;
}
p = L->next;
while (p)
{
cout << p->data << "\t";
p = p->next;
}
cout << endl;
}
5.查询值
5.1按位置查找值
bool Link_GetElem(LinkList* &L, int i, int &e)//单链表的取值
{
//在带头结点的单链表L中查找第i个元素
//用e记录L中地i个元素的值
int index;
LinkList* p;
if (!L || !L->next) return false;
p = L->next;
index = 1;
while (p && index < i)//顺向向后扫描,直到p指向第i个元素或p为空
{
p = p->next;//p指向下一个结点
index++;//计数器index相应加1
}
if (!p || index > i)
return false;//i值不合法,i>n或i<=0
e = p->data;
return true;
}
5.2按值查找
bool Link_FindElem(LinkList* L, int e, int &index)//按值查找
{
//在带头结点的单链表L中查找值为e的元素
LinkList* p;
p = L->next;
index = 1;
if (!L || !L->next)
{
index = 0;
return false;
}
while (p && p->data != e)
{
p = p->next;
index++;
}
if (!p)
{
index = 0;
return false;//查无此值
}
return true;
}
6.单链表的删除
//单链表的删除
bool LinkDelete(LinkList * &L, int i)
{
LinkList* p, *q;
int index = 0;
p = L;
if (!L || !L->next) return false;
while ((p->next) && (index < i - 1))
{
p = p->next;
index++;
}
if (!p->next || (index > i - 1))//当i>n或i<1时,删除位置不合法
{
return false;
}
q = p->next;//临时保存被删结点的地址以备释放空间
p->next = q->next;//改变删除结点前驱结点的指针域
delete q;//释放被删除结点的空间
return true;
}
7.链表销毁
void LinkDestroy(LinkList*& L)//单链表的销毁
{
//定义临时结点p指向头结点
LinkList* p = L;
cout << "销毁链表!" << endl;
while (p)
{
L = L->next;//L指向下一个结点
delete p;//删除当前结点
p = L;//p移向下一个结点
}
}
完整代码
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
typedef struct _LinkNode
{
int data; //结点的数据域
struct _LinkNode* next; //结点的指针域
}LinkNode, LinkList; //LinkList 为指向结构体LNode 的指针类型
bool InitList(LinkList*& L)
{
L = new LinkNode;
if (!L) return false;//生成节点失败
L->next = NULL;
L->data = -1;
return true;
}
//前插法
bool ListInsert_front(LinkList*& L, LinkNode* node)
{
if (!L || !node) return false;
node->next = L->next;
L->next = node;
return true;
}
//尾插法
bool ListInsert_back(LinkList*& L, LinkNode* node)
{
LinkNode* last = NULL;
if (!L || !node) return false;
last = L;
while (last->next) last = last->next;
node->next = NULL;
last->next = node;
return true;
}
//指定位置插入
bool LinkInsert(LinkList*& L, int i, int& e)
{
if (!L) return false;
int j = 0;
LinkList* p, * s;
p = L;
while (p && j < i - 1)
{
//查找位置为i-1 的结点,p 指向该结点
p = p->next;
j++;
}
if (!p || j > i - 1)
{
return false;
}
s = new LinkNode;//生成新节点
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
void LinkPrint(LinkList*& L)
{
LinkNode* p = NULL;
if (!L)
{
cout << "链表为空." << endl;
return;
}
p = L->next;
while (p)
{
cout << p->data << "\t";
p = p->next;
}
cout << endl;
}
bool Link_GetElem(LinkList*& L, int i, int& e)//单链表的取值
{
//在带头结点的单链表L 中查找第i 个元素
//用e 记录L 中第i 个数据元素的值
int index;
LinkList* p;
if (!L || !L->next) return false;
p = L->next;
index = 1;
while (p && index < i)
{
//顺链表向后扫描,直到p 指向第i 个元素或p 为空
p = p->next; //p 指向下一个结点
index++; //计数器index 相应加1
}
e = p->data;
return true;
}
bool Link_FindElem(LinkList* L, int e, int& index) //按值查找
{
//在带头结点的单链表L 中查找值为e 的元素
LinkList* p;
p = L->next;
index = 1;
if (!L || !L->next)
{
index = 0;
return false;
}
while (p && p->data != e)
{
p = p->next;
index++;
}
if (!p)
{
index = 0;
return false;//查无此值
}
return true;
}
bool LinkDelete(LinkList*& L, int i) //单链表的删除
{
LinkList* p, * q;
int index = 0;
p = L;
if (!L || !L->next)
{
return false;
}
while ((p->next) && (index < i - 1))
{
p = p->next;
index++;
}
if (!p || index > i)
{
return false; //i 值不合法,i>n 或i<=0
}
if (!p->next || (index > i - 1))
{
//当 i>n 或 i<1 时,删89除7位94置38不40合1理111
return false;
}
q = p->next; //临时保存被删结点的地址以备释放空间
p->next = q->next;//改变删除结点前驱结点的指针域
delete q; //释放被删除结点的空间
return true;
}
void LinkDestroy(LinkList*& L) //单链表的销毁
{
//定义临时节点p 指向头节点
LinkList* p = L;
cout << "销毁链表!" << endl;
while (p)
{
L = L->next;//L 指向下一个节点
cout << "删除元素: " << p->data << endl;
delete p; //删除当前节点
p = L; //p 移向下一个节点
}
}
int main(void)
{
LinkList* L = NULL;
LinkNode* s = NULL;
//1. 初始化一个空的链表
InitList(L);
//2. 使用前插法插入数据
/*int n;
cout<<"前插法创建单链表"<<endl;
std::cout<<"请输入元素个数n:";
cin>>n;
cout<<"\n 请依次输入n 个元素:" <<endl;
while(n>0)
{
s = new LinkNode; //生成新节点s
cin>>s->data;
ListInsert_front(L, s);
n--;
}
*/
//3. 使用尾插法插入数据
/*
int n;
cout<<"尾插法创建单链表"<<endl;
std::cout<<"请输入元素个数n:";
cin>>n;
cout<<"\n 请依次输入n 个元素:" <<endl;
while(n>0)
{
s = new LinkNode; //生成新节点s
cin>>s->data;
ListInsert_back(L, s);
n--;
}
*/
//4. 单链表的输出
LinkPrint(L);
//5.任意位置插入元素
for (int j = 0; j < 3; j++)
{
int i, x;
cout << "请输入插入的位置和元素(用空格隔开):";
cin >> i;
cin >> x;
if (LinkInsert(L, i, x)) {
cout << "插入成功.\n\n";
}
else {
cout << "插入失败!\n\n";
}
LinkPrint(L);
}
//6. 单链表根据位置获取元素
int element = 0;
if (Link_GetElem(L, 2, element))
{
cout << "获取第二个元素成功, 值:" << element << endl;
}
else
{
cout << "获取第二个元素失败!" << endl;
}
//7. 单链表根据值查询元素所在的位置
int index = 0;
if (Link_FindElem(L, 10, index))
{
cout << "查找元素10 存在,所在位置: " << index << endl;
}
else
{
cout << "不存在元素10." << endl;
}
//8. 单链表删除元素
if (LinkDelete(L, 2))
{
cout << "删除第2 个元素成功!" << endl;
LinkPrint(L);
}
else
{
cout << "删除第2 个元素失败!" << endl;
}
//9. 销毁单链表
LinkDestroy(L);
system("pause");
return 0;
}
参考资料:
奇牛学院