一、双向链表
1、单链表构成的循环链表
最后一个结点本来指向NULL,改为指向头结点或者第一个结点。
实现方法,将原来指向NULL的地方改成指向ls->head,或者ls->head->next。
While()循环的条件改为!= ls->head或者ls->head->next。
#include "Linklist.h"
#include <stdlib.h>
#include <stdio.h>
List *Creat()
{
List *ls = (List *)malloc(sizeof(List)/sizeof(char));
if(NULL == ls)
return NULL;
ls->head = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == ls->head)
{
free(ls);
return NULL;
}
ls->head->next = NULL;
ls->head->pre = NULL;
return ls;
}
//头插
BOOL inster_head(List *ls,Data data)
{
if(NULL == ls)
return ERROR;
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == pa)
return ERROR;
pa->data = data;
pa->next = ls->head->next;
pa->pre = ls->head;
ls->head->next = pa;
if(pa->next != NULL)
pa->next->pre = pa;
return TRUE;
}
//尾插
BOOL inster_last(List *ls,Data data)
{
if(NULL == ls)
return ERROR;
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == pa)
return ERROR;
pa->data = data;
pa->next = NULL;
Node *tmp = ls->head;
while(tmp->next)
{
tmp = tmp->next;
}
tmp->next = pa;
pa->pre = tmp;
return TRUE;
}
//链表按位置插
BOOL inster_pos(List *ls,int index,Data data)
{
if(NULL == ls || index < 1)
return ERROR;
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == pa)
return ERROR;
Node *tmp = ls->head;
int i;
for(i = 0; i < index-1; i++)
{
tmp = tmp->next;
if(tmp == NULL)
{
printf("链表越界,长度=%d\n",index);
return ERROR;
}
}
pa->data = data; //要插入的数据
pa->next = tmp->next;
pa->pre = tmp;
tmp->next = pa;
if(pa->next != NULL)
pa->next->pre = pa;
return TRUE;
}
//删除数据(按位置)
BOOL delete_index(List *ls,int index)
{
if(NULL == ls)
return;
Node *tmp = ls->head;
int i;
for(i = 0; i < index-1; i++)
{
tmp = tmp->next;
if(NULL == tmp || NULL == tmp->next)
{
printf("链表越界,长度=%d\n",index);
return ERROR;
}
}
Node *p = tmp->next;
tmp->next = p->next;
if(p->next != NULL)
p->next->pre = tmp;
free(p);
return TRUE;
}
//删除数据(按数据)
BOOL delete_pos(List *ls,Data data)
{
if(NULL == ls)
return;
Node *tmp = ls->head;
while(tmp->next)
{
if(tmp->next->data == data)
{
Node *p = tmp->next;
tmp->next = p->next;
if(p->next != NULL)
p->next->pre = tmp;
free(p);
return TRUE;
}
tmp = tmp->next;
}
return FALSE;
}
//逆序
BOOL Reverse(List *ls)
{
if(NULL == ls || NULL == ls->head)
return ERROR;
if(NULL == ls->head->next)
{
printf("链表为空\n");
return FALSE;
}
if(NULL == ls->head->next->next)
{
printf("链表只有1个无需逆序\n");
return FALSE;
}
Node *cur = ls->head->next; //第一个结点
while(cur->next)
{
Node *tmp = cur->next; //保存指向下一个地址
cur->next = cur->pre;
cur->pre = tmp;
cur = tmp;
}
ls->head->next->next = NULL;
cur->next = cur->pre;
ls->head->next = cur;
return TRUE;
}
//打印
void Display(List *ls)
{
if(NULL == ls)
return;
Node *tmp = ls->head->next;
while(tmp)
{
printf("%-4d",tmp->data);
tmp = tmp->next;
}
printf("\n");
}
//删除链表
void Destroy(List *ls)
{
if(NULL == ls)
return;
Node *tmp = ls->head;
while(tmp->next)
{
Node *p = tmp->next;
tmp->next = p->next;
free(p);
}
free(ls->head);
free(ls);
}
二、循环链表
1、逆序
//循环链表
#include "Linklist.h"
#include <stdlib.h>
#include <stdio.h>
//创建
List *Creat()
{
List *ls = (List *)malloc(sizeof(List)/sizeof(char));
if(NULL == ls)
return NULL;
ls->head = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == ls->head)
{
free(ls);
return NULL;
}
ls->head->next = ls->head;
return ls;
}
//头插
BOOL inster_head(List *ls,Data data)
{
if(NULL == ls)
return ERROR;
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == pa)
return ERROR;
pa->data = data;
pa->next = ls->head->next;
ls->head->next = pa;
return TRUE;
}
//尾插
BOOL inster_last(List *ls,Data data)
{
if(NULL == ls)
return ERROR;
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == pa)
return ERROR;
pa->data = data;
pa->next = ls->head;
Node *tmp = ls->head;
while(tmp->next != ls->head)
{
tmp = tmp->next;
}
tmp->next = pa;
return TRUE;
}
//链表按位置插
BOOL inster_pos(List *ls,int index,Data data)
{
if(NULL == ls || index < 1)
return ERROR;
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == pa)
return ERROR;
Node *tmp = ls->head;
int i;
for(i = 0; i < index-1; i++)
{
tmp = tmp->next;
if(tmp == ls->head)
{
printf("链表越界,长度=%d\n",index);
return ERROR;
}
}
pa->data = data; //要插入的数据
pa->next= tmp->next;
tmp->next = pa;
return TRUE;
}
//删除数据(按位置)
BOOL delete_index(List *ls,int index)
{
if(NULL == ls)
return;
Node *tmp = ls->head;
int i;
for(i = 0; i < index-1; i++)
{
tmp = tmp->next;
if(ls->head == tmp || ls->head == tmp->next)
{
printf("链表越界,长度=%d\n",index);
return ERROR;
}
}
Node *p = tmp->next;
tmp->next = p->next;
free(p);
return TRUE;
}
//删除数据(按数据)
BOOL delete_pos(List *ls,Data data)
{
if(NULL == ls)
return;
Node *tmp = ls->head;
while(tmp->next !=ls->head)
{
if(tmp->next->data == data)
{
Node *p = tmp->next;
tmp->next = p->next;
free(p);
return TRUE;
}
tmp = tmp->next;
}
return FALSE;
}
//逆序
BOOL Reverse(List *ls)
{
if(NULL == ls || NULL == ls->head)
return ERROR;
if(ls->head == ls->head->next)
{
printf("链表为空\n");
return FALSE;
}
if(ls->head == ls->head->next->next)
{
printf("链表只有1个无需逆序\n");
return FALSE;
}
Node *pre = ls->head->next; //第一个结点
Node *cur = pre->next; //要换的结点
Node *tmp; //保存指向下一个地址
while(cur != ls->head)
{
tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
ls->head->next->next = ls->head;
ls->head->next = pre;
return TRUE;
}
//打印
void Display(List *ls)
{
if(NULL == ls)
return;
Node *tmp = ls->head->next;
while(tmp != ls->head)
{
printf("%-4d",tmp->data);
tmp = tmp->next;
}
printf("\n");
}
//删除链表
void Destroy(List *ls)
{
if(NULL == ls)
return;
Node *tmp = ls->head;
while(tmp->next != ls->head)
{
Node *p = tmp->next;
tmp->next = p->next;
free(p);
}
free(ls->head);
free(ls);
}
三、双向循环链表
将双向链表改成循环链表的技巧
(1)将双向链表中的一些NULL改成ls->head。
(2)去除最后一个结点是否是NULL的判断
#include "Linklist.h"
#include <stdlib.h>
#include <stdio.h>
List *Creat()
{
List *ls = (List *)malloc(sizeof(List)/sizeof(char));
if(NULL == ls)
return NULL;
ls->head = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == ls->head)
{
free(ls);
return NULL;
}
ls->head->next = ls->head;
ls->head->pre = ls->head;
return ls;
}
//头插
BOOL inster_head(List *ls,Data data)
{
if(NULL == ls)
return ERROR;
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == pa)
return ERROR;
pa->data = data;
pa->next = ls->head->next;
pa->pre = ls->head;
ls->head->next = pa;
pa->next->pre = pa;
return TRUE;
}
//尾插
BOOL inster_last(List *ls,Data data)
{
if(NULL == ls)
return ERROR;
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == pa)
return ERROR;
pa->data = data;
pa->next = ls->head;
Node *tmp = ls->head;
while(tmp->next != ls->head)
{
tmp = tmp->next;
}
tmp->next = pa;
pa->pre = tmp;
return TRUE;
}
//链表按位置插
BOOL inster_pos(List *ls,int index,Data data)
{
if(NULL == ls || index < 1)
return ERROR;
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == pa)
return ERROR;
Node *tmp = ls->head;
int i;
for(i = 0; i < index-1; i++)
{
tmp = tmp->next;
if(tmp == ls->head)
{
printf("链表越界,长度=%d\n",index);
return ERROR;
}
}
pa->data = data; //要插入的数据
pa->next = tmp->next;
pa->pre = tmp;
tmp->next = pa;
pa->next->pre = pa;
return TRUE;
}
//删除数据(按位置)
BOOL delete_index(List *ls,int index)
{
if(NULL == ls)
return;
Node *tmp = ls->head;
int i;
for(i = 0; i < index-1; i++)
{
tmp = tmp->next;
if(ls->head == tmp || ls->head == tmp->next)
{
printf("链表越界,长度=%d\n",index);
return ERROR;
}
}
Node *p = tmp->next;
tmp->next = p->next;
p->next->pre = tmp;
free(p);
return TRUE;
}
//删除数据(按数据)
BOOL delete_pos(List *ls,Data data)
{
if(NULL == ls)
return;
Node *tmp = ls->head;
while(tmp->next != ls->head)
{
if(tmp->next->data == data)
{
Node *p = tmp->next;
tmp->next = p->next;
p->next->pre = tmp;
free(p);
return TRUE;
}
tmp = tmp->next;
}
return FALSE;
}
//逆序
BOOL Reverse(List *ls)
{
if(NULL == ls || NULL == ls->head)
return ERROR;
if(ls->head == ls->head->next)
{
printf("链表为空\n");
return FALSE;
}
if(ls->head == ls->head->next->next)
{
printf("链表只有1个无需逆序\n");
return FALSE;
}
Node *cur = ls->head->next; //第一个结点
while(cur != ls->head)
{
Node *tmp = cur->next; //保存指向下一个地址
cur->next = cur->pre;
cur->pre = tmp;
cur = tmp;
}
Node *tmp = cur->next;
cur->next = cur->pre;
cur->pre = tmp;
return TRUE;
}
//打印
void Display(List *ls)
{
if(NULL == ls)
return;
Node *tmp = ls->head->next;
while(tmp != ls->head)
{
printf("%-4d",tmp->data);
tmp = tmp->next;
}
printf("\n");
}
//删除链表
void Destroy(List *ls)
{
if(NULL == ls)
return;
Node *tmp = ls->head;
while(tmp->next != ls->head)
{
Node *p = tmp->next;
tmp->next = p->next;
free(p);
}
free(ls->head);
free(ls);
}