分享

内核链表(十字链表)的学生选课代码

 星天术语 2012-08-04
/*
本程序是一个关于选课(班)的一个小系统,用的是十字链表的知识,其实就是内核链表。其实自己感觉上挺经典的。呵呵!写了半天,当然此代码也是在前辈的框架的基础上写的。
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define container_of(ptr, type, number)  \
(type *)(((char *)ptr) - (unsigned long)(&(((type *)0)->number)))
//核心在此之上。。
struct node{
struct node *prev;
struct node *next;

};

struct class{
char buf[128];
struct node sel;
struct node s_head;
};

struct student{
char buf[128];
int age;
int sex;
struct node sel;
struct node c_head;
};

struct item{
struct class *c;
struct student *s;
struct node s_sel;
struct node c_sel;
};

void add_node(struct node *head, struct node *new)
{
new->next = head;
new->prev = head->prev;
head->prev->next = new;
head->prev = new;
}

void add_stu(struct node *student, struct node *class)
{
struct student *old = NULL;
struct item *item = NULL;
char buf[128];

struct node *tail = NULL;
struct node *last = NULL;

struct class *tmp = NULL;

while(1)
{
printf("plese enter student :\t");
fgets(buf, sizeof(buf) - 1, stdin);
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';

if(!strncasecmp(buf, "end", 3))
{
break;
}

old = (struct student *)malloc(sizeof(struct student));

strcpy(old->buf, buf);
AA: old->age = rand() % 20;
if(old->age < 15)
goto AA;
old->sex = rand() % 2;

old->c_head.next = &old->c_head;
old->c_head.prev = &old->c_head;

add_node(student, &old->sel);

for(tail = class->next; tail != class; tail = tail->next)
{
tmp = container_of(tail, struct class, sel);
printf("%s \t class :[Y / N] \t:", tmp->buf);
char ch;

scanf("%c", &ch);

while(getchar() != '\n')
;

if(ch == 'Y' || ch == 'y')
{

item = (struct item *)malloc(sizeof(struct item));


item->s = old;
item->c = tmp;

add_node(&old->c_head, &item->c_sel);

add_node(&tmp->s_head, &item->s_sel);


}
}
}
}

void travel(struct node *head_c)
{
struct node *tail = NULL;
struct node *last = NULL;

struct class *new = NULL;
struct item *old = NULL;

for(tail = head_c->next; tail != head_c; tail = tail->next)
{
new = container_of(tail, struct class, sel);

printf("\nclass : %s\t ", new->buf);

for(last = new->s_head.next; last != &new->s_head; last = last->next)
{
old = container_of(last, struct item, s_sel);

printf("[%s]", old->s->buf);
printf("-[%d]-[%d]\t", old->s->age, old->s->sex);
}
putchar('\n');
}
}

void add_cls(struct node *head, struct node *s_head)
{
struct class *new = NULL;
struct node *tail = NULL;
struct item *item = NULL;
struct student *student = NULL;
char buf[128];

new = (struct class *)malloc(sizeof(struct class));
printf("please enter add class :\t");

fgets(buf, sizeof(buf) - 1, stdin);
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) -1 ] = '\0';
strcpy(new->buf, buf);

new->s_head.next = &new->s_head;
new->s_head.prev = &new->s_head;

add_node(head, &new->sel);

printf("%s class -> is_add student :[Y / N]\t", new->buf);

char ch;

ch = getchar();

while(getchar() != '\n')
;

if(ch == 'y' || ch == 'Y')
{

for(tail = s_head->next; tail != s_head; tail = tail->next)
{
student = container_of(tail, struct student, sel);
printf("IS_ADD [%s] student \t", student->buf);

ch = getchar();

while(getchar() != '\n')
;

if(ch == 'N' || ch == 'n')
continue;

item = (struct item *)malloc(sizeof(struct item));
item->s_sel.next = &new->s_head;
item->s_sel.prev = new->s_head.prev;
new->s_head.prev->next = &item->s_sel;
new->s_head.prev = &item->s_sel;
item->c_sel.next = &student->c_head;
item->c_sel.prev = student->c_head.prev;

student->c_head.prev->next = &item->c_sel;
student->c_head.prev = &item->c_sel;

item->s = student;
item->c = new;
}
}
}

void find_cls(struct node *head)
{
struct node *tail = NULL;
struct node *last = NULL;

struct class *class = NULL;
struct student *student = NULL;
struct item *item = NULL;
char buf[128];
printf("please enter want find class :\t");

fgets(buf, sizeof(buf) - 1, stdin);
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
for(tail = head->next; tail != head; tail = tail->next)
{
class = container_of(tail, struct class, sel);

if(!strcmp(class->buf, buf))
{
printf("class: %s student number:\t");

for(last = class->s_head.next; last != &class->s_head; last = last->next)
{
item = container_of(last, struct item, s_sel);

printf("%s\t", item->s->buf);
}
}
}
}

void find_student(struct node *s_head)
{
struct node *tail = NULL;
struct student *student = NULL;

struct class *class = NULL;
struct item *item = NULL;

struct node *last = NULL;
char buf[128];

printf("please enter student :\t");

fgets(buf, sizeof(buf) - 1, stdin);
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';


for(tail = s_head->next; tail != s_head; tail = tail->next)
{
student = container_of(tail, struct student, sel);
if(!strcmp(buf, student->buf))
{
for(last = student->c_head.next; last != &student->c_head; last = last->next)
{
item = container_of(last, struct item, c_sel);
printf("[%s]", item->c->buf);
}
return;
}

}
}

void show_class(struct node *c_head)
{
struct node *tail = NULL;
struct class *class = NULL;

struct class *student = NULL;

printf("all class list :\t");

for(tail = c_head->next; tail != c_head; tail = tail->next)
{
class = container_of(tail, struct class, sel);

printf("[%s] ", class->buf);
}
}

void show_student(struct node *s_head)
{
struct node *tail = NULL;
struct student *student = NULL;

printf("all student list :\t");

for(tail = s_head->next; tail != s_head; tail = tail->next)
{
student = container_of(tail, struct student, sel);

printf("[%s] ", student->buf);
}
}

void delete_class(struct node *c_head, struct node *s_head)
{
struct node *new = NULL;

struct node *tail = NULL;
struct node *last = NULL;

struct class *class = NULL;
struct student *student = NULL;
struct item *item = NULL;
char buf[128];

printf("you want to delete class : ");
fgets(buf, sizeof(buf) - 1,  stdin);
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
for(tail = c_head->next; tail != c_head; tail = tail->next)
{
class = container_of(tail, struct class, sel);

if(!strcmp(buf, class->buf))
{

for(last = class->s_head.next; last != &class->s_head; last = last->next)
{

item = container_of(last, struct item, s_sel);

item->s_sel.prev->next = item->s_sel.next;
item->s_sel.next->prev = item->s_sel.prev;
item->c_sel.prev->next = item->c_sel.next;
item->c_sel.next->prev = item->c_sel.prev;
item->s = NULL;
item->c = NULL;
free(item);
item = NULL;
}

tail->prev->next = tail->next;
tail->next->prev = tail->prev;

free(class);
class = NULL;

return;
}

}
}

void delete_student(struct node *c_head, struct node *s_head)
{
struct node *tail = NULL;
struct node *last = NULL;

struct class *class = NULL;
struct student *student = NULL;

struct item *item = NULL;
char buf[128];

printf("please enter want to student :\t");

fgets(buf, sizeof(buf) - 1, stdin);
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
for(tail = s_head->next; tail != s_head; tail = tail->next)
{
student = container_of(tail, struct student, sel);

if(!strcmp(buf, student->buf))
{
for(last = student->c_head.next; last != &student->c_head; last = last->next)
{
item = container_of(last, struct item, c_sel);

item->s = NULL;
item->c = NULL;

item->s_sel.prev->next = item->s_sel.next;
item->s_sel.next->prev = item->s_sel.prev;

item->c_sel.prev->next = item->c_sel.next;
item->c_sel.next->prev = item->c_sel.prev;

free(item);
item = NULL;
}

student->sel.next->prev = student->sel.prev;
student->sel.prev->next = student->sel.next;

free(student);

student = NULL;

return;
}
}

}

static void destroy_s(struct node *head)
{
struct node *tail = NULL;
struct student *student = NULL;

for(tail = head->next; tail != head; tail = tail->next)
{
student = container_of(tail, struct student, sel);

student->sel.next->prev = student->sel.prev;
student->sel.prev->next = student->sel.next;

free(student);
student = NULL;
}
}

static void destroy_c(struct node *c_head, struct node *s_head)
{
struct node *tail = NULL;
struct class *class  = NULL;

struct student *student = NULL;
struct item *item = NULL;
struct node *last = NULL;

for(tail = c_head->next; tail != c_head; tail = tail->next)
{
class = container_of(tail, struct class, sel);

for(last = class->s_head.next; last != &class->s_head; last = last->next)
{
item = container_of(last, struct item, s_sel);

item->c_sel.next->prev = item->c_sel.prev;
item->c_sel.prev->next = item->c_sel.next;

item->s_sel.next->prev = item->s_sel.prev;
item->s_sel.prev->next = item->s_sel.next;

item->s = NULL;
item->c = NULL;

free(item);
item = NULL;
}

class->sel.next->prev = class->sel.prev;
class->sel.prev->next = class->sel.next;

free(class);
class = NULL;
}
}

void destroy(struct node *c_head, struct node *s_head)
{
destroy_c(c_head, s_head);

destroy_s(s_head);
}

int main(void)
{
struct node head_s = {.next = &head_s, .prev = &head_s};
struct node head_c = {.next = &head_c, .prev = &head_c};
struct class *new = NULL;
int quit = 0;

char buf[128];


while(1)
{
printf("please enter class :\t");
fgets(buf, sizeof(buf) - 1, stdin);
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';


if(!strncasecmp(buf, "END", 3))
{
break;
}

new = (struct class *)malloc(sizeof(struct class));

strcpy(new->buf, buf);
new->s_head.next = &new->s_head;
new->s_head.prev = &new->s_head;
add_node(&head_c, &new->sel);
}

while(!quit)
{
printf("==== 1  -> add student    ===\n");
printf("==== 2  -> add class      ===\n");
printf("==== 3  -> find class     ===\n");
printf("==== 4  -> find student   ===\n");
printf("==== 5  -> tarvel all     ===\n");
printf("==== 6  -> show class     ===\n");
printf("==== 7  -> show sudent    ===\n");
printf("==== 8  -> delete class   ===\n");
printf("==== 9  -> delete student ===\n");
printf("==== 10 -> destroy        ===\n");

printf("input your want number: \t");

int num = 0;

scanf("%d", &num);

while(getchar() != '\n')
;
switch(num)
{
case 1:
add_stu(&head_s, &head_c);
putchar('\n');
break;

case 2:
add_cls(&head_c, &head_s);
putchar('\n');
break;
case 3:
find_cls(&head_c);
putchar('\n');
break;

case 4:
find_student(&head_s);
putchar('\n');
break;

case 5:
travel(&head_c);
putchar('\n');
break;
case 6:
show_class(&head_c);
putchar('\n');
break;
case 7:
show_student(&head_s);
putchar('\n');
break;

case 8:
delete_class(&head_c, &head_s);
putchar('\n');
break;

case 9:
delete_student(&head_c, &head_s);
putchar('\n');
break;

case 10:
quit = !quit;
break;

default:
break;
}
}

destroy(&head_c, &head_s);

return 0;
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多