1.链表的概念
■链式存储结构中,逻辑上相邻的元素在物理存储上不一定相邻。
结点包括:结点本身数据信息,元素之间的关联关系。
■线性表用链式方式将结点链接起来的存储结构称为链表。
■从链接方式看,可分为单链表、循环链表和双向链表。
■从实现角度看,可分为动态链表和静态链表。
2.线性表的链式存储
■线性链表(单链表) :用一组任意的存储单元存放线性表的结点每个结点的唯一后继依靠一个结点指针维持。
■链表中的结点包括数据域和指针域两个域
●数据域data :存储结点的值,
●指针域next :存储后继结点的位置(地址)
■头指针Head指向第一一个结点,最后一个结点的指针域为"空”(NULL)
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#define OK 1
#define ERROR 0
#define Elemtype int
#define MAXSIZE 100
#define ERROR1 -1
using namespace std;
typedef struct LNode
{
Elemtype data;
LNode * next;
}LNode, *Linklist;
void InitList_L(Linklist & L); //建空表,并且初始化
void CreateList1(Linklist & L, int n); //头插法
void CreateList2(Linklist & L, int n); //尾插法
int GetElem(Linklist L, int i, Elemtype &e); //根据位置i获取数据元素的内容,取值
int LocateElem(Linklist L, int e); //根据指定数据获取所在的位置,查找
int ListInsert_Sq(Linklist &L, int i, Elemtype e); //插入
int ListDelete_Sq(Linklist &L, int i, Elemtype &e); //删除
int showList(Linklist L); //输出
int main()
{
int i;
Elemtype e, m;
int n;
Linklist L;
InitList_L(L);
cin >> n;
CreateList1(L, n);
std::cout << "取值,输入:" << std::endl;
std::cin >> i;
if (!GetElem(L, i, e))
std::cout << "输入无效" << std::endl;
else
std::cout << e << std::endl;
std::cout << "查找,输入:" << std::endl;
std::cin >> m;
if (!LocateElem(L, m))
std::cout << "未找到" << std::endl;
else
std::cout << LocateElem(L, m) << std::endl;
//插入
std::cout << "插入,输入:" << std::endl;
std::cin >> i >> e;
int r;
if (!(r = ListInsert_Sq(L, i, e)))
std::cout << "输入无效" << std::endl;
else if (!(r + 1))
std::cout << "空间已满" << std::endl;
else
showList(L);
//删除
std::cout << "删除,输入:" << std::endl;
std::cin >> i;
int k;
if (!ListDelete_Sq(L, i, k))
std::cout << "删除无效" << std::endl;
else
showList(L);
}
void InitList_L(Linklist & L)
{
L = new LNode;//L = (Linklist)malloc(sizeof(LNode))
L->next = NULL;
}
void CreateList1(Linklist & L, int n)
{
Linklist s;
for (int i = n; i > 0; i++)
{
s = new LNode;
cin >> s->data;
s->next = L->next;
L->next = s;
}
}
void CreateList2(Linklist & L, int n)
{
Linklist h = L;
Linklist r;
for (int i = n; i > 0; i++)
{
r = new LNode;
cin >> r->data;
r->next = NULL;
h->next = r;
h = r;
}
}
int GetElem(Linklist L, int i, Elemtype &e)
{
Linklist p = L->next;
int j = 1;
while (p&&j < i)
{
p = p->next;
j++;
}
if (!p || j > i)
return ERROR;
else
{
e = p->data;
return OK;
}
}
int LocateElem(Linklist L, int e)
{
int i = 0;
Linklist p = L->next;
while (!p&&p->data != e)
i++;
if (!p)
return ERROR;
else
return i + 1;
}
int ListInsert_Sq(Linklist &L, int i, Elemtype e)
{
Linklist p = L, s;
int j = 0;;
while (j < i - 1 && p)
{
p = p->next;
j++;
}
if (!p || j > i - 1)
return ERROR;
else
{
s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
}
int ListDelete_Sq(Linklist &L, int i, Elemtype &e)
{
Linklist p = L, s;
int j = 0;
while (p->next&&j < i - 1)
{
p = p->next;
j++;
}
if (!p->next&&j > i - 1)
return ERROR;
else
{
s = p->next;
e = s->data;
p->next = s->next;
delete p;
return OK;
}
}
int showList(Linklist L)
{
Linklist p = L->next;
while (!p)
{
cout << p->data;
p = p->next;
}
return 0;
}
链表的优缺点
优点:
-数据元素的个数可以自由扩充
-插入、删除等操作不必移动数据,只需修改链接指针,修改效率较高
缺点:
-存储密度小.
-存取效率不高,必须采用顺藤摸瓜似的顺序存取