链表的基本操作-学生考勤demo

117 阅读3分钟

#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);
}