链式存储结构的基本知识
链表:n个结点由指针链组成一个链表
构成结点:有数据域和指针域。
头指针:是指向链表的第一个结点的指针。
头结点:是在链表的首元结点之前附设的一个结点。
首元节点:头结点的后继结点,是链表中存储第一个数据元素a1的结点。
1:链表设头结点的好处。
-
便于首元结点的处理
-
便于空表和非空表的处理
-
设置头节点在表空时不产生野指针。
-
注意:头结点不能计入链表长度值。
单链表的数据类型
typedef struct Lnode
{
Elemtype data;
struct Lnode* next;//利用嵌套定义指向结点的指针类型。
}Londe,*Linklist;
我们通常遇到的问题数据域有好多数据对象需要使用所以为了统一操作可以使用如下定义方法
typedef struct
{
string a;
int b;
char c;//等等
}Elemtype;
typedef struct Lnode
{
Elemtype data;
struct Lnode* next;//利用嵌套定义指向结点的指针类型。
}Londe,*Linklist;
2:单链表基本操作的实现。
2.1:单链表的初始化
status1 init_link(Linklist& L)
{
L = new Lnode;// new创建数据 返回这个数据的地址 也就是指针.
//由此可知L就是头指针所以初始化链表要定义一个指向该类型的指针用来接收头结点的地址。
L->next = NULL;
}
2.2判断链表是否为空。
判断链表为空则判断头结点的指针域是否为空算法如下(换句话讲就是判断是否有首元结点)。
status2 judje_link(Linklist& L)
{
if (L->next)//要知道if的这种用法。
{
return true;
}
return false;
}
2.3单链表的销毁
从头指针开始依次释放所有结点。
status1 destroy_link(Linklist& L)
{
Lnode* p;
while (L)
{
p = L;
L = p->next;
delete p;
}
}
2.4清空链表
链表仍然存在,但链表中无元素成为空链表。
算法思路:依次释放所有结点头结点置空。
status1 empty_link(Linklist& L)
{
Lnode* p, * q;
q=L->next;
while (q)
{
p = q->next;
delete q;
q = p;
}
L->next = NULL;
}
2.5求单链表的长度
status length_link(Linklist& L)
{
Lnode* p;
int i = 0;
p = L->next;//注意头结点不算所以从首元结点开始
while (p)
{
i++;
p = p->next;
}
return i;
}
2.6 取值——取单链表中的第i个元素。
算法思想
从首元结点开始依次扫描计数器加一,当j==i时则找到。
Linklist value1_link(Linklist& L,int i)//直接返回地址
{
Lnode* p;
int j = 0;
p = L->next;
while (p)
{
j++;
if (j == i)
{
return p;
}
p = p->next;
}
}
2.7 按值查找——根据指定数据获取该数据位置。
算法思想
从首元结点起依次和e比较。
Linklist value2_link(Linklist L, Elemtype e)//直接返回地址
{
Lnode* p;
p = L->next;
while (p&&p->data != e)
{
p = p->next;
}
return p;
}
2.8算法插入 在第i个结点前插入元素e
算法思想 找ai-1的位置。
status2 insert_link(Linklist& L,int i, Elemtype e)
{
Londe* p, * q, * k;
p = L;
int j = 0;
while (p&&j<i-1)
{
p = p->next;
j++;
}
/*if (P)就是if(P != NULL), 不为空执行语句
if (!P)就是if(P == NULL), 为空执行语句*/
if (!p || j > i - 1)
{
return false;
}
k = new Lnode;
k->data = e;
k->next = p->next;
p->next = k;
}
2.9算法——删除 删除第i个结点。
算法思想 找ai-1的位置。保存要删除的ai的值。
status dt_link(Linklist& L, int i, Elemtype e)
{
Lnode* p, * q;
p = L; int j = 0;
while (p && j < i - 1)
{
p = p->next;
j++;
}
if (!p || j > i - 1)
{
return 0;
}
q = p->next;
p->next = q->next;
e = q->data;
delete q;
}
3.0算法——建立单链表 头插法。
/*3.0算法——建立单链表 头插法。*/
status1 great_link(Linklist& L, int n)
{
L = new Lnode;
L->next = NULL;
Lnode* p, * q;
for (int i = 0; i <n; i++)
{
p = new Londe;
p->next = L->next;//注意这里头结点不变变得是首元结点 。
cin >> p->data;
L->next = p;
}
}
3.1算法——建立单链表 尾插法
status1 great1_link(Linklist& L, int n)
{
Lnode* p, * q;
L = new Lnode;
L->next = NULL;
q = L;
for (int i = 0; i < n; i++)
{
p= new Lnode;
cin >> p->data;
p->next = NULL;
q->next = p;
q = p;
}
}