首先设计链表的结点结构体,表结构体和测试用学生结构体。普通链表只能存放单一数据类型,而通用式链表可以存放各种数据类型,因此节点的data域设置为void,输出时强转为我们需要的数据类型。这里以存放student类型数据举例。
ELEMSIZE大小为四字节,如果存放的数据大于四字节则存放在data中,如果大于四字节则另外开辟一块空间,让data指向此空间。
1.购买节点
使用malloc开辟一块空间用于存放数据并memset设置初始值为0.
2.释放节点
3.购买节点
如果传入的elemsize大于四字节则开辟新空间,大小为sizeof(char)*elemsize,并设置初始值为0.
.
4.释放节点
这里释放的是存放数据大于四字节新开辟的空间。
5.初始化链表
购买节点并设置prev,next指向及各项赋初始值。
6.清空链表
当链表非空,则删除最后一个元素,直至删完。
7.摧毁链表
清空链表并释放节点
8.获取链表长度
链表不为空时返回plist的元素个数。
9.判空
判断链表中元素个数是否为0,满足则返回。
10.在元素p前插入pval
首先购买节点并设置指针指向,如果插入的pval字节不大于4,就将pval的值拷贝给s的data域。如果pval字节大于四字节则用上边写的buyelem新开辟空间es并将pval拷贝给es的data域,最后链表长度+1.
11.头插,尾插
直接调用insertprev,头插将plist->head->next传入insertprev即在第一个节点前插入。
尾插将plist->head传入在头节点前插入即在最后一个节点后插入。
12.打印链表
如果存入元素字节小于4,则打印p本身的data值。如果大于4,则打印p指向区域的data值。
13.删除元素
如果元素字节大于4则只设置指针指向。
如果字节大于4就设置指针值指向并释放另外开辟空间。
最后元素个数-1.
14.头删,尾删
尾删即删除头节点前一个元素,将plist->head->prev传入erase即删除最后一个元素。
头删即删除出头节点外第一个元素,将plist->head->next传入erase即删除第一个元素。
15.查找元素
定义指针p遍历链表,如果元素字节大于4,则将p的data与要查找的pval对比相等则返回p。
如果元素字节大于4,则将p指向的data与pval比较相等返回p。
查找失败反回空。
16.获取第一位/最后一位元素
链表非空下如果元素字节小于4,将pdata=plist->head->next->data的值拷贝给pval,即第一个元素。
如果元素字节大于4,将pdata指向区域的data值拷贝给pval.
元素字节小于4,将pdata=plist->head->prev->data的值拷贝给pval,即最后一个元素。
如果元素字节大于4,将pdata指向区域的data值拷贝给pval.
17.删除元素
利用fandval找到后用erase删除。
18.主函数测试
#define _CRT_SECURE_NO_WARNINGS
#include"GenLinkList.hpp"
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
void printstudent(void* p) {
student* cp = (student*)p;
printf("学号:%s,姓名:%s,性别:%s,年龄:%d\n", cp->id, cp->name, cp->sex, cp->age);
}
int main() {
LinkList ilist;
InitList(&ilist, sizeof(student));
student s1 = { "001","zs","man",14 };
student s2 = { "002","ls","man",15 };
student s3 = { "003","few","man",35 };
student s4 = { "004","gr","woman",23 };
student s5 = { "005","kwe","woman",10 };
student s6 = { "006","khjq","man",20 };
Push_back(&ilist, &s1);
Push_back(&ilist, &s2);
Push_back(&ilist, &s3);
Push_front(&ilist, &s4);
Push_front(&ilist, &s5);
Push_front(&ilist, &s6);//插入
printElem(&ilist, printstudent);
printf("\n----------------------------------- \n");
pop_back(&ilist);//尾删
pop_front(&ilist);//头删
printElem(&ilist, printstudent);//输出
student stu1;
GetFront(&ilist, &stu1);
printstudent(&stu1);//获取第一个
student stu2;
GetBack(&ilist, &stu2);
printstudent(&stu2);//获取最后一个
student stu;//查询
memset(&stu, 0, sizeof(student));
while (scanf("%s %s %s %d", stu.id, stu.name, stu.sex, &stu.age), stu.age != -1) {
ListNode* p = findval(&ilist, &stu);
if (NULL == p) {
printf("find err");
}
else {
printf("%p\n", p);
printstudent(p->data);
}
}
DestroyList(&ilist);//销毁
return 0;
}
输入查找值