單鏈表最爲人熟悉,隨便一搜都講的很好,所以還是不要獻醜,直接上代碼吧。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
typedef struct LNode
{
void *data; // 這裏設成指針型是因爲 這裏儲存是要操作的數據的首地址,通過該數據域的地址(4個字節)操作它,提高效率,而無類型是爲了通用
struct LNode *next;
}NODE;
typedef struct
{
NODE *head; //頭指針 頭指針是指向頭結點的指針 而頭結點是單鏈表第一個結點之前的一個結點,數據域可以不存儲任何信息,指針域指向第一個結點
NODE *last; //尾指針
int length;
}LinkList;
typedef struct students
{
char sno[5];
char name[21];
int age;
float score;
}STU;
STU s[6] = {
{"S001","lin wu",12,90},
{"S002","xiao ming",13,80},
{"S003","wang wu",11,100},
{"S004","xiao hong",14,24},
{"S005","zhang san",15,45},
{"S006","li xi",19,90}
};
LinkList *CreateList(); // 創建鏈表
int AppendList(LinkList *l, void *data, int size); // 在鏈表最後追加結點
int InsertList(LinkList *l, int n, void *data, int size); // 在第 n 個結點之前插入一個結點
void PrintList(LinkList *l, void (* printnode)(void *)); // 打印
NODE *FindBykey(LinkList *l, void *key, int (*compare)(void *, void *)); // 按關鍵字查找
NODE *FindNode(LinkList *l, void *key, int (*compare)(void *, void *), NODE **pre); // 查找關鍵字結點之前的那個結點
int DeleteByKey(LinkList *l, void *key, int (*compare)(void *,void*)); // 按關鍵字刪除
int DeleteByIndex(LinkList *l, int index, void *e, int size); // 按位置刪除,並返回所刪結點數據域到 e
void PrintData(void *data)
{
STU *t = (STU *)data;
printf("%-5s %-10s %5d %5f\n",t->sno,t->name,t->age,t->score);
}
int CompareByName(void *info, void *name)
{
STU *t = (STU *)info;
char *s = (char *)name;
return strcmp(t->name, s) == 0 ? 1 : 0;
}
int main()
{
int i;
LinkList *list = CreateList();
char name[21];
NODE *res = NULL;
STU *e = (STU *)malloc(sizeof(STU));
for (i = 0; i < 4; ++i)
{
AppendList(list, &s[i], sizeof(s[i]));
}
PrintList(list, PrintData);
printf("\n\n");
InsertList(list, 3, &s[4], sizeof(s[4]));
PrintList(list, PrintData);
printf("\n\n");
res = FindBykey(list, name, CompareByName);
if (NULL == res)
{
printf("Not Find!\n");
}
else
{
printf("Find!\n");
}
printf("\n\n");
AppendList(list, &s[5], sizeof(s[5]));
PrintList(list, PrintData);
printf("\n\n");
DeleteByIndex(list, 1, e, sizeof(STU));
printf("所刪結點的數據:\n");
printf("%-5s %-10s %5d %5f\n\n",e->sno,e->name,e->age,e->score);
PrintList(list, PrintData);
printf("\n\n");
printf("請輸入想要刪除的學生名字:");
// scanf("%s",name);
gets(name);
DeleteByKey(list, name, CompareByName);
PrintList(list, PrintData);
printf("\n\n");
return 0;
}
// 創建鏈表
LinkList *CreateList()
{
LinkList *l = (LinkList *)malloc(sizeof(LinkList));
if (NULL == l)
{
exit(0);
}
memset(l,0,sizeof(LinkList));
NODE *pHead = (NODE *)malloc(sizeof(NODE));
if (NULL == pHead)
{
exit(0);
}
memset(pHead, 0, sizeof(NODE));
l->head = pHead;
return l;
}
// 在鏈表最後追加結點
int AppendList(LinkList *l, void *data, int size)
{
NODE *n = NULL;
if (NULL == l || NULL == data)
{
return 0;
}
n = (NODE *)malloc(sizeof(NODE));
if (NULL == n)
{
return 0;
}
n->data = malloc(size);
if (NULL == n->data)
{
free(n);
return 0;
}
memcpy(n->data, data, size);
if (NULL == l->head->next)
{
l->head->next = n;
}
else
{
l->last->next = n;
}
l->last = n;
n->next = NULL; // 最後一個結點的指針域指向空 也可以寫成l->last->next = NULL;
l->length++;
return 1;
}
// 在第 n 個結點之前插入一個結點
int InsertList(LinkList *l, int n, void *data, int size)
{
NODE *p = NULL, *t = NULL;
int i = 0;
if (NULL == l || NULL == data || n < 1 || n > l->length)
{
return 0;
}
p = l->head;
while (i < n - 1)
{
p = p->next;
++i;
}
t = (NODE *)malloc(sizeof(NODE));
if (NULL == t)
{
return 0;
}
t->data = malloc(size);
if (NULL == t->data)
{
free(t);
return 0;
}
memcpy(t->data, data, size);
t->next = p->next;
p->next = t;
l->length++;
return 1;
}
// 打印
void PrintList(LinkList *l, void (* printnode)(void *))
{
NODE *p = NULL;
int i;
if (NULL == l || NULL == printnode)
{
return;
}
p = l->head->next;
for (i = 0; i < l->length && NULL != p; ++i)
{
printnode(p->data);
p = p->next;
}
}
// 按關鍵字查找
NODE *FindBykey(LinkList *l, void *key, int (*compare)(void *, void *))
{
NODE *p = NULL;
int i = 0;
if (NULL == l || NULL == key || NULL == compare)
{
return NULL;
}
p = l->head;
while (i < l->length)
{
p = p->next;
if (1 == compare(p->data, key))
{
return p;
}
++i;
}
return NULL;
}
// 查找關鍵字結點之前的那個結點
NODE *FindNode(LinkList *l, void *key, int (*compare)(void *, void *), NODE **pre)
{
NODE *p = NULL;
if (NULL == l || NULL == key || NULL == compare || pre == NULL)
{
return NULL;
}
p = l->head;
*pre = NULL;
while (p)
{
p = p->next;
if (1 == compare(p->data,key))
{
return p;
}
*pre = p;
}
return NULL;
}
// 按關鍵字刪除
int DeleteByKey(LinkList *l, void *key, int (*compare)(void *,void*))
{
NODE *p = NULL , *q = NULL;
p = FindNode(l,key,compare,&q);
if (NULL == p)
{
return 0;
}
if (NULL == q)
{
l->head->next = p->next;
}
else
{
q->next = p->next;
}
if (p == l->last)
{
l->last = q;
}
free(p->data);
free(p);
l->length--;
return 1;
}
// 按位置刪除,並返回所刪結點數據域到 e
int DeleteByIndex(LinkList *l, int index, void *e, int size)
{
NODE *p = NULL, *q = NULL;
int i = 0;
if (NULL == l || index < 1 || index > l->length)
{
return 0;
}
p = l->head;
while (i < index - 1)
{
p = p->next;
++i;
}
q = p->next;
// e = malloc(sizeof(size));
memcpy(e, q->data, size);
// e = q->data;
p->next = q->next;
free(q->data);
free(q);
l->length--;
return 1;
}