#Linked list的基本操作及使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OVERFLOW -2
#define ERROR -1
#define OK 0
typedef struct _student {
char sno[20];
char sname[20];
int isAttendance;
} Stu;
typedef Stu ElemType;
typedef struct _node {
ElemType data; // data field
struct _node *next; // pointer field
} LNode;
int listInit(LNode **L);
int listDestroy(LNode *L);
int listClear(LNode *L);
int listLength(LNode L);
// 插入节点-头插法
int listInsertNodeHead(LNode *L, ElemType data);
// 插入结点-尾插法
int listInsertNodeTail(LNode *L, ElemType data);
// 按照位置查找元素并返回
int listFindElemByPos(LNode L, int position, ElemType *returnElem);
// 返回0表示查询不到此信息,否则返回元素位置
int listFindElemByVal(LNode L, ElemType value);
// 按照位置更新元素
int listUpdateNodeByPos(LNode *L, int pos, ElemType data);
// 判断元素是否相等
int listElemIsEqual(ElemType e1, ElemType e2);
// 考勤模块
LNode* enroll(LNode *L);
void elemInit(LNode *L);
void printList(LNode L);
void printAbsence(LNode L);
int main(int argc, char *argv[]) {
LNode *L, *newL;
// 链表初始化
listInit(&L);
// 名单初始化
elemInit(L);
printList(*L);
// 考勤模块
newL = enroll(L);
printf("\n本次考勤信息:\n------------------------------\n");
// 打印签到名单
printList(*newL);
// 打印缺勤名单
printAbsence(*newL);
return 0;
}
int listInit(LNode **L) {
(*L) = (LNode*)malloc(sizeof(LNode));
if (*L == NULL)
return ERROR;
(*L)->next = NULL;
return OK;
}
int listDestroy(LNode *L) {
LNode *p;
while (L) {
p = L;
L = L->next;
free(p);
}
return OK;
}
int listClear(LNode *L) {
LNode *p, *q;
p = L->next; // 头指针->头节点->首元节点
while (p) {
q = p->next;
free(p);
p = q;
}
L->next = NULL;
return OK;
}
int listLength(LNode L) {
LNode *p = L.next;
int count = 0;
while (p) {
count ++;
p = p->next;
}
return count;
}
int listFindElemByPos(LNode L, int pos, ElemType *returnElem) {
LNode *hNode = L.next; // head node
int i;
for ( i = 1; i < pos; i++) {
hNode = hNode->next;
}
if (!hNode || i > pos)
return ERROR;
*returnElem = hNode->data;
return OK;
}
// equal: 0 inequal: -1
int listElemIsEqual(ElemType e1, ElemType e2) {
int ret = -1;
if (strcmp(e1.sno, e2.sno) == 0)
ret = 0;
return ret;
}
// 返回0表示查询不到此信息,否则返回元素位置
int listFindElemByVal(LNode L, ElemType elem) {
int count = 1;
LNode *p = (&L)->next;
for (int i = 1; p; i++) {
if (listElemIsEqual(p->data, elem) == 0) {
break;
}
count++;
p = p->next;
}
if (p == NULL)
return 0;
else
return count;
}
int listUpdateNodeByPos(LNode *L, int pos, ElemType data) {
LNode *p = L->next;
if (pos < 1 || pos > listLength(*L))
return ERROR;
for (int i = 1; p; i++) {
if (i == pos) {
p->data = data;
break;
}
p = p->next;
}
return OK;
}
int listInsertNodeHead(LNode *L, ElemType data) {
LNode *newNode = (LNode*)malloc(sizeof(LNode));
if (newNode == NULL)
return ERROR;
newNode->data = data;
newNode->next = L->next;
L->next = newNode;
return OK;
}
int listInsertNodeTail(LNode *L, ElemType data) {
LNode *p, *tailNode, *newNode;
p = L->next;
newNode = (LNode*)malloc(sizeof(LNode));
newNode->data = data;
if (!p) {
newNode->next = NULL;
L->next = newNode;
} else {
while (p) {
tailNode = p; // record last a node
p = p->next;
}
newNode->next = NULL;
tailNode->next = newNode;
}
return OK;
}
LNode* enroll(LNode *L) {
char tempSno[20];
while (1) {
printf("input stuno pls:\n");
scanf(" %s", tempSno);
if (strcmp("999", tempSno) == 0) {
break;
}
ElemType stu, updateStu;
strcpy(stu.sno, tempSno);
// 找到学生位置,pos为0则表示名单中暂无该学生
int pos = listFindElemByVal(*L, stu);
if (pos != 0) {
// 获取到学生信息
listFindElemByPos(*L, pos, &updateStu );
// 设置已签到
updateStu.isAttendance = 1;
// 更新学生信息
listUpdateNodeByPos(L, pos, updateStu);
}
}
return L;
}
void elemInit(LNode *L) {
ElemType stu1, stu2, stu3;
strcpy(stu1.sno, "001");
strcpy(stu2.sno, "002");
strcpy(stu3.sno, "003");
strcpy(stu1.sname, "Tom");
strcpy(stu2.sname, "Jack");
strcpy(stu3.sname, "Roby");
stu1.isAttendance = 0;
stu2.isAttendance = 0;
stu3.isAttendance = 0;
listInsertNodeTail(L, stu1);
listInsertNodeTail(L, stu2);
listInsertNodeTail(L, stu3);
}
void printList(LNode L) {
printf("学号\t姓名\t出勤\n");
LNode *p = L.next;
while (p) {
printf("%s\t%s\t%d\n", p->data.sno, p->data.sname, p->data.isAttendance);
p = p->next;
}
printf("------------------------------\n当前名单人数:%d\n\n", listLength(L));
}
void printAbsence(LNode L) {
LNode *p = L.next;
int count = 0;
printf("\n缺勤学生有:\n\n");
printf("学号\t姓名\n");
while (p) {
if (p->data.isAttendance == 0) {
printf("%s\t%s\n", p->data.sno, p->data.sname);
count++;
}
p = p->next;
}
printf("\n本次考勤共有%d位同学缺勤\n", count);
}