数据结构-单链表
一 单链表的结构
typedef struct LNode
{
int data; //数据域
struct LNode *next;//指针域
} LNode, *LinkList;
二 单链表的操作
1 单链表的逆置
-1-1 头插法逆置
/******************************************
* 方法一
* 链表原地逆置
* 采用原地重新以头插法创建链表
* *****************************************/
LinkList Inverse_ListLink(LinkList &L)
{
LNode *p, *r;
p = L->next;
L->next = NULL; //头部指针指空
while (p)
{
/* code */
r = p->next;
p->next = L->next;
L->next = p;
p = r;
}
cout << "逆置完成!" << endl;
return L;
}
-1-2 三指针依次逆置
/******************************************
* 方法二
* 链表原地逆置
* 依次逆置
* *****************************************/
LinkList Inverse_ListLink_Two(LinkList &L)
{
LNode *a, *b = L->next, *c = b->next;
b->next = NULL; //b的后继结点已存取,故可置空
while (c)
{
/* code */
a = c->next;
c->next = b;
b = c;
c = a;
}
//循环结束则 此时c为NULL 而b为最后一个结点
L->next = b;
cout << "逆置完成!" << endl;
return L;
}
2 单链表的排序
-2-1 插入排序法O(n2)
/******************************************
* 方法二
* 链表原地逆置
* 依次逆置
* *****************************************/
LinkList Inverse_ListLink_Two(LinkList &L)
{
LNode *a, *b = L->next, *c = b->next;
b->next = NULL; //b的后继结点已存取,故可置空
while (c)
{
/* code */
a = c->next;
c->next = b;
b = c;
c = a;
}
//循环结束则 此时c为NULL 而b为最后一个结点
L->next = b;
cout << "逆置完成!" << endl;
return L;
}
-2-2 附加数组快排法O(nlog2n)
快速排序法将数组排序,时间复杂度为O(nlog2n)
3 单链表的公共结点
-3-1 暴力对比法O(n*m)
待补充
-3-2 具有公共结点的单链表尾部链一致
待补充
4 单链表的拆分与合并
-4-1 两个有序单链表的归并
-4-1-1 递减合并
/*************************************
* 链表合并
* 假设有两个按元素值递增次序排列的线性表,
* 均以单链表形式存储。将这两个单链表归并为一个按元素值 “递减次序” 排列的单链表,要求使用原来两个单链表的结点存放归并后的链表
* ***********************************/
LinkList Merge_List(LinkList &L1, LinkList &L2)
{
LNode *head, *p, *pa = L1->next, *pb = L2->next;
L1->next = NULL;//使用L1的头节点作为合并后链表的头节点 头节点置空
while (pa != NULL && pb != NULL)
{
/* code */
if (pa->data <= pb->data)//头插法插入链表
{
p = pa->next;
pa->next = L1->next;
L1->next = pa; //插入完成
pa = p; //重新赋值为工作结点
}
else
{
p = pb->next;
pb->next = L1->next;
L1->next = pb; //插入完成
pb = p; //重新赋值为工作结点
}
}
//结束则存在一个为指空的结点
if(pa == NULL)
{
pa = pb;
}
while (pa != NULL)//插入剩余的结点
{
p = pa->next;
pa->next = L1->next;
L1->next = pa; //插入完成
pa = p; //重新赋值为工作结点
}
delete(L2);
return L1;
}
-4-1-2 递增合并
/*************************************
* 链表合并:递增次序--插入思想
* 假设有两个暗元素值递增次序排列的线性表,
* 均以单链表形式存储。将这两个单链表归并为一个按元素值 “递增次序” 排列的单链表,要求使用原来两个单链表的结点存放归并后的链表
* ***********************************/
LinkList Decrease_List(LinkList &L1, LinkList &L2)
{
LNode *p, *q, *pa = L1->next, *pb = L2->next;
p = L1;
L1->next = NULL;
while(pa != NULL && pb != NULL)
{
if(pa->data <= pb->data)
{
q = pa->next;
p->next = pa;
pa->next = NULL;
pa = q;
}
else
{
q = pb->next;
p->next = pb;
pb->next = NULL;
pb = q;
}
p = p->next;
}
if(pa == NULL)
{
pa = pb;
}
p->next = pa;
delete(L2);
return L1;
}
三 循环单链表的操作
1 循环删除最小值操作
/***********************************
* 循环 删除“循环单链表”中的最小的元素
* page-42-19
* *******************************/
void DelEle_CycleList(LinkList &L)
{
cout<<"循环删除最小的元素"<<endl;
LNode *head = L,*p;
LNode *min_pre = L, *min_node = L->next;
p = min_node;
while (head->next != head)
{
/* code */
min_pre = head;
min_node = head->next;
p = min_node;
while (p->next != head) //一次循环结束
{
if(p->next->data < min_node->data)
{
min_pre = p;
min_node = p->next;
}
p = p->next;
}
//输出并删除min_node
min_pre->next = min_node->next;
cout<<"value:"<<min_node->data<<endl;
}
delete(min_node);
}
2 创建操作:尾插法
LinkList Cycle_List_TailInsert(LinkList &L)
{
int value;
L = new LNode;
LNode *p, *tail = L; //tail为尾指针 创建尾指针以降低时间复杂度
cout << "Input: ";
while (cin >> value)
{
/* code */
p = new LNode; //申请空间
p->data = value;
tail->next = p;
tail = p; // L->......->...->tail => L->......->p->tail=P
cout << "Input: ";
}
tail->next = L; //创建完成 令尾节点指向空
cout << "创建完成!" << endl;
//由于输入流是以输入 EOF 结束 ,为避免影响下次输入操作 删除流中的数据
cin.clear();
return L; //返回头节点
}
3 合并两个循环单链表
-1 头尾对接 A->B->A
//合并两个循环单链表
LinkList CycleList_Add_CycleList(LinkList &L1, LinkList &L2)
{
LNode *ra = L1, *rb = L2;
//找到各自的尾节点
while (ra->next != L1)
ra = ra->next;
while (rb->next != L2)
rb = rb->next;
ra->next = L2->next;//除去L2的头节点
//ra->next = L2;// 不除去L2的头节点
rb->next = L1;
return L1;
}
未完待续。。。