#include <stdio.h>
#include <stdlib.h>
typedef struct DuLNode {
int data;
struct DuLNode *piror;
struct DuLNode *next;
} DuLNode, *DuLinkList ;
//创建链表用LinkList
//创建结点用LNode
//初始化
void InitList_DuL(DuLinkList *L);
//置空
void ClearList_DuL(DuLinkList L);
//销毁
//插入
//删除
//是否空
//返回元素个数
//获取第i个结点的值
//接收某元素的前驱
//接收某元素的后继
//遍历链表
void InitList_L(DuLinkList *L) {
(*L) = (DuLinkList)malloc(sizeof(DuLNode));
if (!(*L))
return exit(-1);
(*L)->next = (*L)->piror = (*L); //空的循环链表指向自身
}
void ClearList_DuL(DuLinkList L) {
//1 temp指向首元结点
//2 循环 判断temp是否和头指针L相同
//3 依次交换指针指向
DuLinkList temp1, temp2;
temp1 = L->next; //保留头结点
while (temp1 != L) {
temp2 = temp1->next;
free(temp1);
temp1 = temp2;
}
}
void DestoryList_DuL(DuLinkList *L) {
//调用clear函数
//释放头指针指向的内存空间
//头指针指向null
ClearList_DuL(*L);
free(*L);
(*L) = NULL;
}
int IsEmpty_DuL(DuLinkList L) {
//判断链表L的pior指针和next指针是否都指向头指针?
if (L && L->next != L && L->piror != NULL)
return 0;
return 1;
}
int ListLength_DuL(DuLinkList L) {
//1 temp指向头结点
//2 遍历循环链表 条件(结点尾指针!=头指针)
DuLinkList temp;
int count;
if (L) {
temp = L; //temp指向头结点 L就是头指针 *L就是头结点
count = 0;
while (temp->next != L) { //没到表头
count++;
temp = temp->next;
}
}
return count;
}
void GetElem_DuL(DuLinkList L, int i, int *e) {
//temp指向首元结点 计数器从1开始
//遍历循环 条件(temp!=头指针 && count<i)
//
DuLinkList temp;
int count;
if (L) {
temp = L->next; //除去头结点
count = 1; //不数头结点,故从1开始
while (temp != L && count < i) {
count++;
temp = temp->next;
}
if (temp != L) {
*e = temp->data;
}
}
}
//返回L中第一个与e满足compare的关系的元素的位序
int LocateElem_DuL(DuLinkList L, int e, int(* compare)(int, int)) {
//判断L是否合法
//指针指向首元结点
//循环链表(temp!=头指针,函数指针取反)
// temp不是头指针 返回计数count(位序)
DuLinkList temp;
int count;
if (L) {
temp = L->next;
count = 1;
while (temp != L && !compare(e, temp->data)) { //data<e
count++;
temp = temp->next;
}
if (temp != L)
return count;
}
return 0;
}
//寻找元素cur_e的前驱元素,用per_e接收
void priorElem_DuL(DuLinkList L, int cur_e, int *pre_e) {
//首元结点
//循环链表(不为头结点,数据不为cur_e),找到和cur_e相同的元素就退出
//找到的结点不为头结点且前驱也不为头结点
DuLinkList temp;
if (L) {
temp = L->next;
// 寻找和数据域和cur_e相同的结点
while (temp != L && temp->data != cur_e) {//当前结点的数据和cur_e不相同
temp = temp->next;
}
if (temp != L && temp->piror != L) { //前驱不为头结点
*pre_e = temp->piror->data;
}
}
}
void NextElem_DuL(DuLinkList L, int cur_e, int *nex_e) {
DuLinkList temp;
if (L) {
temp = L->next;
while (temp != L && temp->data != cur_e) {
temp = temp->next;
}
if (temp != L && temp->next != L) {
*nex_e = temp->next->data;
}
}
}
//返回指向第i个结点的指针 不包括头结点
DuLinkList GetElemPtr_DuL(DuLinkList L, int i) {
DuLinkList temp;
int count;
if (L && i > 0) {
count = 1;
temp = L->next;
while (temp != L && count < i) {
count++;
temp = temp->next;
}
if (temp != L)
return temp;
}
return NULL;
}
//待定
void ListInsert_DuL(DuLinkList L, int i, int e) {
DuLinkList temp, newbase;
if (i < 1 || i > ListLength_DuL(L) + 1)
return;
temp = GetElemPtr_DuL(L, i); //找到插入位置的结点
if (!temp)
temp = L;
newbase = (DuLinkList)malloc(sizeof(DuLNode));
if (!newbase)
return;
newbase->data = e;
newbase->next = temp->next;
newbase->piror = temp;
temp->next = newbase;
temp->next->piror = newbase;
// printf("%d\n", newbase->data);
/*正确版本
DuLinkList p, s;
if (i < 1 || i > ListLength_DuL(L) + 1) {
return;
}
p = GetElemPtr_DuL(L, i);
if (!p)
p = L;
s = (DuLinkList)malloc(sizeof(DuLNode));
if (!s)
return;
s->data = e;
s->piror = p->piror;
p->piror->next = s;
s->next = p;
p->piror = s;
printf("%d\n", s->data);*/
}
void ListDelete(DuLinkList L, int i, int *e) {
DuLinkList temp;
if (i < 0 || i > ListLength_DuL(L) + 1)
return;
temp = GetElemPtr_DuL(L, i);
if (!temp)
return;
*e = temp->data;
temp->piror->next = temp->next;
temp->next->piror = temp->piror;
free(temp);
temp = NULL;
}
//遍历链表
void ListTraverse_DuL(DuLinkList L, void(*Vist)(int)) {
DuLinkList temp;
temp = L->next;
while (temp != L) {
Vist(temp->data);
temp = temp->next;
}
printf("\n");
}
int compare(int e, int data) {
return data > e ? 1 : 0;
}
void visit(int e) {
printf("%d", e);
}
//void (*Vist)(int);
int main() {
DuLNode temp;
DuLinkList L;
L = &temp;
InitList_L(&L);
// Vist = visit;
for (int i = 1; i < 6; i++) {
ListInsert_DuL(L, i, i);
}
ListTraverse_DuL(L, visit);
return 0;
}