一、雙向鏈表
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);
}