目录
链表定义
链表是线性表的链式存储方式,逻辑上相邻的数据在计算机内的存储位置不必须相邻,那么
怎么表示逻辑上的相邻关系呢?可以给每个元素附加一个指针域,指向下一个元素的存储位
置。如图所示:
从图中可以看出,每个结点包含两个域:数据域和指针域,指针域存储下一个结点的地址,
因此指针指向的类型也是结点类型
链表
的核心要素:
每个节点由数据域和指针域组成
指针域指向下一个节点的内存地址
其结构体定义:
typedef struct LinkNode
{
ElemType data;
struct LinkNode *next;
}*LinkList, LinkNode;
1.初始化链表
typedef struct _LinkNode
{
int data;//结点的数据域
struct _LinkNode *next;//结点的指针域
}LinkNode,*LinkList;
bool InitList(LinkList &L) //链表的初始化
{
L = new LinkNode;
if (!L) return false;
L->next = NULL;
return true;
}
2.前插法增加元素
//前插法
bool ListInsertFront(LinkList &L,LinkNode* node)
{
if (!L || !node) return false;
node->next = L->next;
L->next = node;
}
3.插入数据
//在第i的位置上插入数据
bool ListInsert(LinkList &L, int i, int e)
{
LinkNode *p, *s;
p = L;
int j = 0;
//先找到第i-1个结点的位置
while (p && j<i-1)
{
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;
}
4.链表的遍历,销毁原理理解较为简单,查找原理与插入相似。
完整链表操作源码:
//LinkList.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
/*
* Author:See
* QQ:3492625357
*/
#include <iostream>
using namespace std;
typedef struct _LinkNode
{
int data;//结点的数据域
struct _LinkNode *next;//结点的指针域
}LinkNode,*LinkList;
bool InitList(LinkList &L) //链表的初始化
{
L = new LinkNode;
if (!L) return false;
L->next = NULL;
return true;
}
//前插法
bool ListInsertFront(LinkList &L,LinkNode* node)
{
if (!L || !node) return false;
node->next = L->next;
L->next = node;
}
//尾插法
bool ListInsertBack(LinkList &L, LinkNode* node)
{
if (!L || !node) return false;
LinkNode* last=L;
//先找到尾部结点
while (last->next) last = last->next;
//再插入结点到尾部
last->next = node;
node->next = NULL;
return true;
}
//在第i的位置上插入数据
bool ListInsert(LinkList &L, int i, int e)
{
LinkNode *p, *s;
p = L;
int j = 0;
//先找到第i-1个结点的位置
while (p && j<i-1)
{
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;
}
//单链表的取值 第i位置上的结点数据赋值给e
bool LinkGetElem(LinkList L, int i, int &e)
{
LinkNode *p, *s;
p = L;
int j = 0;
//找到第i结点的位置
while (p&&j<i)
{
p = p->next;
j++;
}
if (!p || j > i) return false;
e = p->data;
return true;
}
//删除第i个结点
bool LinkDelete(LinkList &L, int i)
{
LinkNode *p,*q;
p = L;
int j = 0;
//找到第 i-1 个结点的位置
while (p&&j<i-1)
{
p = p->next;
j++;
}
if (!(p->next) && j > i - 1) return false;
q = p->next;//q临时保存i结点,用于释放空间
p->next = q->next;
delete q;
return true;
}
void PrintList(LinkList L)
{
LinkNode *p = L->next;
while (p)
{
cout << p->data << "\t";
p = p->next;
}
cout << endl;
}
//销毁链表
void LinkDistroy(LinkList &L)
{
LinkNode *p = L;
while (p)
{
L = L->next;
delete p;
p = L;
}
}
int main()
{
//1.初始化一个空链表
LinkList L;
InitList(L);
//2.前插法
int n;
LinkNode* s;
cout << "请输入插入的整数个数: " << endl;
cin >> n;
cout << "请依次输入"<<n<<"个整数:" << endl;
while (n--)
{
s = new LinkNode;
cin >> s->data;
s->next = NULL;
ListInsertFront(L, s);
}
PrintList(L);
//3.测试ListInsert
cout << "调用 ListInsert(LinkList &L, int i, int e)," << " 请输入位置 i 和整数 e"<<endl;
int i, e;
cin >> i >> e;
ListInsert(L, i, e);
PrintList(L);
//4.取值
cout << "输入你要查找的结点i" <<endl;
cin >> i;
LinkGetElem(L, i, e);
cout << i << "结点的数据为: " << e << endl;
//5.删除结点
cout << "输入你要删除的结点i" << endl;
cin >> i;
LinkDelete(L, i);
PrintList(L);
//6.销毁链表
LinkDistroy(L);
system("pause");
return 0;
}