单向循环链表原理
简单来说就是单链表的尾节点指向了头结点
结构体定义
typedef struct LinkList
{
int data;
struct LinkList* next;
}LinkList, LinkNode;
单向循环链表代码实现
初始化
在初始化中将头结点的指针指向了自己
//初始化
bool initLink(LinkList*& L)
{
L = new LinkList;
if (!L) return false;
L->data = 0;
L->next = L;
return true;
}
遍历
只需要注意的是while的循环条件,是不等于头结点
void printLink(LinkList*& L)
{
if (!L) return;
LinkNode* p = L->next;
while (p != L)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
销毁
这里要注意不能写成类似单链表中的销毁形式,因为单向循环链表再删除尾节点的时候,尾节点的next指向的是野指针,程序会报错。
void destroyLink(LinkList*& L)
{
if (!L) return;
LinkNode* p = L->next;
L->next = NULL;
while (L)
{
L = p->next;
delete p;
p = L;
}
}
插入
前插法
bool insert_front(LinkList*& L, int val)
{
if (!L) return false;
LinkNode* node = new LinkNode;
node->data = val;
node->next = L->next;
L->next = node;
return true;
}
尾插法
bool insert_back(LinkList*& L, int val)
{
if (!L) return false;
LinkNode* node = new LinkNode;
node->data = val;
node->next = L;
LinkNode* p = L;
while (p->next != L)
{
p = p->next;
}
p->next = node;
return true;
}
任意位置插入
这里要注意一下当我们通过循环来寻找要插入的位置的时候,循环结束的条件,因为这里我的循环条件是p != L,所以我对当插入位置为1的情况进行的单独的实现。(如果有更好的思路希望可以多多交流)
bool insertLink(LinkList*& L, int index, int val)
{
if (!L || index < 1) return false;
if (index == 1)
{
LinkNode* node = new LinkNode;
node->data = val;
node->next = L->next;
L->next = node;
return true;
}
int j = 1;
LinkNode* p = L->next;
while (p != L && j < index - 1)
{
p = p->next;
j++;
}
if (!p) return false;
LinkNode* node = new LinkNode;
node->data = val;
if (L->next == L)
{
node->next = L;
p->next = node;
}
else
{
node->next = p->next;
p->next = node;
}
return true;
}
删除
删除和在任意位置插入同理,同样是注意一下对删除位置的寻找。
bool deleteLink(LinkList*& L, int index)
{
if (!L || index < 1) return false;
if (index == 1)
{
LinkNode* q = L->next;
L->next = q->next;
delete q;
return true;
}
int j = 1;
LinkNode* p = L->next;
while (p != L && j < index - 1)
{
p = p->next;
j++;
}
if (!p) return false;
LinkNode* q = p->next;
p->next = q->next;
delete q;
return true;
}
完整代码
#include <iostream>
using namespace std;
typedef struct LinkList
{
int data;
struct LinkList* next;
}LinkList, LinkNode;
//初始化
bool initLink(LinkList*& L)
{
L = new LinkList;
if (!L) return false;
L->data = 0;
L->next = L;
return true;
}
//遍历
void printLink(LinkList*& L)
{
if (!L) return;
LinkNode* p = L->next;
while (p != L)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
//销毁
void destroyLink(LinkList*& L)
{
if (!L) return;
LinkNode* p = L->next;
L->next = NULL;
while (L)
{
L = p->next;
delete p;
p = L;
}
}
//前插法
bool insert_front(LinkList*& L, int val)
{
if (!L) return false;
LinkNode* node = new LinkNode;
node->data = val;
node->next = L->next;
L->next = node;
return true;
}
//尾插法
bool insert_back(LinkList*& L, int val)
{
if (!L) return false;
LinkNode* node = new LinkNode;
node->data = val;
node->next = L;
LinkNode* p = L;
while (p->next != L)
{
p = p->next;
}
p->next = node;
return true;
}
//任意位置插入
bool insertLink(LinkList*& L, int index, int val)
{
if (!L || index < 1) return false;
if (index == 1)
{
LinkNode* node = new LinkNode;
node->data = val;
node->next = L->next;
L->next = node;
return true;
}
int j = 1;
LinkNode* p = L->next;
while (p != L && j < index - 1)
{
p = p->next;
j++;
}
if (!p) return false;
LinkNode* node = new LinkNode;
node->data = val;
if (L->next == L)
{
node->next = L;
p->next = node;
}
else
{
node->next = p->next;
p->next = node;
}
return true;
}
//删除
bool deleteLink(LinkList*& L, int index)
{
if (!L || index < 1) return false;
if (index == 1)
{
LinkNode* q = L->next;
L->next = q->next;
delete q;
return true;
}
int j = 1;
LinkNode* p = L->next;
while (p != L && j < index - 1)
{
p = p->next;
j++;
}
if (!p) return false;
LinkNode* q = p->next;
p->next = q->next;
delete q;
return true;
}
int main(void)
{
LinkList* L;
initLink(L);
cout << "前插法 插入1 2 3" << endl;
insert_front(L, 1);
insert_front(L, 2);
insert_front(L, 3);
printLink(L);
cout << "尾插法 插入5 6 7" << endl;
insert_back(L, 5);
insert_back(L, 6);
insert_back(L, 7);
printLink(L);
cout << "在第四个位置插入4" << endl;
insertLink(L, 4, 4);
printLink(L);
cout << "删除第五个" << endl;
deleteLink(L, 5);
printLink(L);
destroyLink(L);
return 0;
}