线性表之单向链表
线性表是一种逻辑结构,其中数据以线性形式存储,数据元素之间的关系是“前后”的次序关系。
单向链表
单向链表的结点的数据结构:
将数据以int类型为例,如下
typedef struct node
{
int data;
struct node* next;
}Lnode,*Linklist;
其中Lnode是结点类型,Linklist是结点指针类型。
初始化带头结点的单向链表
int init(Linklist& L)
{
L = new Lnode;
if (L == NULL)
return 0;
L->next = NULL;
}
创建一空结点Lnode作为一个链表头结点。头结点在之后不会参与进任何操作,相比于没有头结点的链表,其所有操作都不需要区分表头位置的操作,更加简洁。
向链表中插入数据
int insert(Linklist& L, int i)
{
Linklist e = new Lnode;
Linklist p = L;
int pos = 0;
while (p)
{
if (pos == i - 1)
{
cout << "Input data" << endl;
cin >> e->data;
e->next = p->next;
p->next = e;
return 1;
}
p = p->next;
pos++;
}
return 0;
}
创建一个结点插入到表中i位置。
寻找表中第i-1个结点位置,若到此处p的位置不为NULL,即存在第i-1个数据,那么就在将L[i-1]->next,即原先第i个数据的位置存放在新生成的结点e的next中,然后把e的位置存放在p,即第i-1个数据的next中,完成插入。
头插法
int headInsert(Linklist& L)
{
Linklist e = new Lnode;
e->next = L->next;
L->next = e;
cout << "Input data" << endl;
cin >> e->data;
return 1;
}
把新数据插入到表中第一个位置,操作方便,时间复杂度O(1)。
尾插法
int rearInsert(Linklist& L)
{
Linklist e = new Lnode, p = L;
while (p->next)
{
p = p->next;
}
cout << "Input data" << endl;
cin >> e->data;
e->next = NULL;
p->next = e;
return 1;
}
把新数据插入到表的结尾,时间复杂度O(n)。
删除表中数据
int remove(Linklist& L, int i)
{
Linklist p = L;
int pos = 0;
while (p->next)
{
if (pos == i - 1)
{
Linklist q = p->next;
p->next = q->next;
free(q);
return 1;
}
p = p->next;
pos++;
}
return 0;
}
删除表中第i个数据结点。
寻找表中第i-1个结点位置,若到此处p->next的位置不为NULL,则说明第i个位置有数据,那么就将第i个元素的next直接覆盖存放在p,即第i-1个元素的next中,完成删除;若在此之前p->next已经为NULL,说明第i个位置没有数据,退出方法。
查找表中数据
int search(Linklist L,int data,Lnode& e)
{
Linklist p = L->next;
while (p)
{
if (p->data == data)
{
e = *p;
return 1;
}
p = p->next;
}
return 0;
}
查找表中数据为data的结点,并返回给e,从第一个结点开始,判断是否为空,若不为空,则开始判断当前结点data是否是是要查找的data,若是则返回,否则继续查找,直到结点为空。
遍历
int traversal(Linklist L)
{
Linklist p = L->next;
while (p)
{
cout << p->data << endl;
p = p->next;
}
return 1;
}
遍历。
就地逆置
int reverse(Linklist& L)
{
Linklist p = L->next, q;
L->next = NULL;
while (p)
{
q = p;
p = p->next;
q->next = L->next;
L->next = q;
}
return 1;
}
用p作为原链表的位置指针,q作为操作指针,将第一个结点的位置,即L->next存放在p中,然后将要操作的链表L置为空表,即L->next = NULL。若p不为空,则将p中位置存放在q中,p中存放p的下一个结点地址p->next,采用头插法的思想,将q中所存放的数据插入到表L中,实现原地逆置。
定位
与遍历类似,添加了比对条件并输出,省略。
以上。