# include <stdio.h>
# include <stdbool.h>
# include <malloc.h>
typedef int DataType;
typedef struct Node {
DataType data;
struct Node * next;
} Node;
/* 需要完成的所有基本操作 */
void InitList_Head(Node **);
void InitList_Tail(Node **);
int Length(Node *);
int LocateElem(Node *, DataType);
DataType GetElem(Node *, int);
bool ListInsert(Node *, int, DataType);
bool ListDelete(Node *, int, DataType *);
void PrintList(Node *);
bool Empty(Node *);
void DestroyList(Node *);
int main(void) {
printf("-insert head-\n");
Node * pHead1;
InitList_Head(&pHead1);
PrintList(pHead1);
printf("\n");
printf("-insert tail-\n");
Node * pHead2;
InitList_Tail(&pHead2);
PrintList(pHead2);
printf("size? %d\n", Length(pHead2));
printf("locate 2? %d\n", LocateElem(pHead2, 6));
printf("GetElem loc 4? %d\n", GetElem(pHead2, 4));
printf("\n");
printf("-insert elem-\n");
ListInsert(pHead2, 4, 0);
PrintList(pHead2);
printf("\n");
printf("-delete elem-\n");
int e;
ListDelete(pHead2, 4, &e);
printf("delete elem? %d\n", e);
PrintList(pHead2);
printf("\n");
printf("empty? %d\n", Empty(pHead2));
printf("\n");
printf("-delete elem-\n");
DestroyList(pHead2);
printf("empty? %d\n", Empty(pHead2));
PrintList(pHead2);
return 0;
}
void InitList_Head(Node ** ppHead) {
/*
1. 建立头结点
2. 循环插入 (头插法)
*/
Node * pHead = (Node *)malloc(sizeof(Node));
/*
此时,pHead中是头结点的地址
*/
pHead->next = NULL;
pHead->data = 9999; // for test
int len = 5;
Node * pNew;
for (int i = 0; i < len; i++) {
pNew = (Node *)malloc(sizeof(Node));
pNew->data = i + 1;
pNew->next = pHead->next;
pHead->next = pNew;
}
*ppHead = pHead;
return;
}
void PrintList(Node * pHead) {
Node * p = pHead->next;
int i = 0; // just for test
/*
注意!!!
pHead存的是头结点的地址
但,
p存的不是pHead存的地址 --> 即头结点的地址
p存的是pHead指向的那个单元中next存的地址 --> 即第一个单元的地址
*/
printf("List's info:\n");
while ((p != NULL) && (i <= 10)) {
printf("data=%d, next=%d\n", p->data, p->next);
p = p->next;
i++;
}
return;
}
void InitList_Tail(Node ** ppHead) {
Node * pHead = (Node *)malloc(sizeof(Node));
pHead->next = NULL;
pHead->data = 999; // just for test
int len = 5;
Node * pNew;
Node * pTail = pHead;
for (int i = 0; i < len; i++) {
pNew = (Node *)malloc(sizeof(Node));
pNew->data = i + 10;
pNew->next = NULL;
pTail->next = pNew;
pTail = pNew;
}
*ppHead = pHead;
return;
}
int Length(Node * pHead) {
int len = 0;
Node * p = pHead->next;
while (p != NULL) {
len++;
p = p->next;
}
return len;
}
int LocateElem(Node * pHead, DataType d) {
int loc = 0;
Node * p = pHead->next;
while (p != NULL && p->data != d) {
/*
四种情况:
p == NULL && p->data == d --> 跳出循环 --> 尾结点是目标点
p == NULL && p->data != d --> 跳出循环 --> 没有目标点
p != NULL && p->data == d --> 跳出循环 --> 尾结点前是目标点
p != NULL && p->data != d --> 继续循环
*/
p = p->next;
loc++;
}
if (p == NULL || p->data != d) {
/*
判定条件不能只写(p->data != d)
因为,若此时p是NULL,则不能访问p->data
*/
return -1; // 没有这个点
}
return loc;
}
DataType GetElem(Node * pHead, int pos) {
Node * p = pHead->next;
int i = 1;
if (pos <= 0) return -888;
while(p != NULL) {
if (i == pos) {
return p->data;
}
p = p->next;
i++;
}
return -999;
}
bool ListInsert(Node * pHead, int pos, DataType d) {
if (pos <= 0) return false;
Node * p = pHead->next;
Node * pPrior = pHead;
int i = 1;
while(p != NULL) {
if (i == pos) {
Node * pNew = (Node * )malloc(sizeof(Node));
pNew->data = d;
pNew->next = p;
pPrior->next = pNew;
return true;
}
p = p->next;
pPrior = pPrior->next;
i++;
}
return false;
}
bool ListDelete(Node * pHead, int pos, DataType * d) {
if (pos <= 0) return false;
Node * p = pHead->next;
Node * pPrior = pHead;
int i = 1;
while (p != NULL) {
if (i == pos) {
*d = p->data;
pPrior->next = p->next;
free(p);
p=NULL;
return true;
}
p = p->next;
pPrior = pPrior->next;
i++;
}
return false;
}
bool Empty(Node * pHead) {
if (pHead->next == NULL) return true;
return false;
}
void DestroyList(Node * pHead) {
pHead->next = NULL;
}