【发布时间】:2011-05-08 13:38:10
【问题描述】:
我正在做一个类似于通讯录的项目。首先,我们在一个文本文件中有许多学生。我将实现一个多链表,该列表有 2 个头+尾指针(名称、姓氏的头+尾指针)。这些指针显示相同的列表但位置不同,因为我按升序添加节点并使用双指针向后打印列表。问题是我通过按姓名和姓氏添加节点来实现列表,当我插入另一个节点时操作成功。但是我意识到,当我按她/他的“姓名”删除一个节点并再次打印列表时,学生不存在,但是当我按“姓”打印列表时,学生确实存在。然后我意识到我实现了两个单独的链表。我被告知只实现一个添加和删除功能。但是如何通过名字指针和姓氏指针一起添加节点呢?我希望我可以理解地解释我的问题。这是我的代码块。
我的结构:
typedef struct node {
int birth_date;
int zipcode;
int phone_num;
char first_name[50];
char last_name[50];
char city[50];
char address[50];
char email_addr[50];
struct node* fn_next;
struct node* fn_pre;
struct node* ln_next;
struct node* ln_pre;
struct node* birdat_next;
struct node* birdat_pre;
} NODE;
typedef struct {
int fn_count;
int ln_count;
NODE* fn_head;
NODE* ln_head;
NODE* fn_tail;
NODE* ln_tail;
}LIST;
我逐行读取文件并调用添加函数的代码块:
while ( !feof(myfile) ) {
NODE* pnew_stu;
if( !(pnew_stu = (NODE*) malloc(sizeof(NODE))) ) {
printf("ERROR NOT ENOUGH MEMORY!!!\n");
exit(100);
}
fscanf(myfile,"%s", &(pnew_stu->first_name) );
fscanf(myfile,"%s", &(pnew_stu->last_name) );
fscanf(myfile,"%s", &(pnew_stu->email_addr) );
fscanf(myfile,"%d", &(pnew_stu->phone_num) );
fscanf(myfile,"%s", &(pnew_stu->address) );
fscanf(myfile,"%s", &(pnew_stu->city) );
fscanf(myfile,"%d", &(pnew_stu->zipcode) );
add_Node(list,pnew_stu);
}
最后是我的添加函数:
void add_fn_Node(LIST* list, NODE* pnew_stu) {
NODE* temp = list->fn_head;
if( list->fn_head == NULL ) {
pnew_stu->fn_next = list->fn_head;
pnew_stu->fn_pre = list->fn_head;
list->fn_head = pnew_stu;
list->fn_count = 1;
return;
}
else {
if ( (strcmp( pnew_stu->first_name, temp->first_name )) <= 0 ) { // Basa Ekleme Kosulu
pnew_stu->fn_next = temp;
pnew_stu->fn_pre = temp->fn_pre;
temp->fn_pre = pnew_stu;
list->fn_head = pnew_stu;
list->fn_count++;
return;
}
else {
while ( temp->fn_next != NULL ) { // Ortaya Ekleme Kosulu
if ( (strcmp( pnew_stu->first_name, temp->first_name ) >= 0 ) && (strcmp( pnew_stu->first_name, temp->fn_next->first_name) < 0)) {
pnew_stu->fn_next = temp->fn_next;
pnew_stu->fn_pre = temp;
temp->fn_next->fn_pre = pnew_stu;
temp->fn_next = pnew_stu;
list->fn_count++;
return;
}
temp = temp->fn_next;
}
if ( temp->fn_next == NULL ) { // Sona Ekleme Kosulu
temp->fn_next = pnew_stu;
pnew_stu->fn_pre = temp;
pnew_stu->fn_next = NULL;
list->fn_tail = pnew_stu;
list->fn_count++;
return;
}
}
}
}
void add_ln_Node(LIST* list, NODE* pnew_stu) {
NODE* temp = list->ln_head;
if( list->ln_head == NULL ) {
pnew_stu->ln_next = list->ln_head;
pnew_stu->ln_pre = list->ln_head;
list->ln_head = pnew_stu;
list->ln_count = 1;
return;
}
else {
if ( (strcmp( pnew_stu->last_name, temp->last_name )) <= 0 ) { // Basa Ekleme Kosulu
pnew_stu->ln_next = temp;
pnew_stu->ln_pre = temp->ln_pre;
temp->ln_pre = pnew_stu;
list->ln_head = pnew_stu;
list->ln_count++;
return;
}
else {
while ( temp->ln_next != NULL ) { // Ortaya Ekleme Kosulu
if ( (strcmp( pnew_stu->last_name, temp->last_name ) >= 0 ) && (strcmp( pnew_stu->last_name, temp->ln_next->last_name) < 0)) {
pnew_stu->ln_next = temp->ln_next;
pnew_stu->ln_pre = temp;
temp->ln_next->ln_pre = pnew_stu;
temp->ln_next = pnew_stu;
list->ln_count++;
return;
}
temp = temp->ln_next;
}
if ( temp->ln_next == NULL ) { // Sona Ekleme Kosulu
temp->ln_next = pnew_stu;
pnew_stu->ln_pre = temp;
pnew_stu->ln_next = NULL;
list->ln_tail = pnew_stu;
list->ln_count++;
return;
}
}
}
}
我的删除功能:
void del_fn_name(LIST* list, char* str_key) {
NODE* temp;
int num,counter=1,flag;
temp = list->fn_head;
if( list->fn_head == NULL ) {
printf("The list is EMPTY!!!\n");
return;
}
flag = search_fn(list,str_key);
if ( flag ) {
printf("Enter the number of student you want to delete : ");
scanf("%d", &num);
if( strcmp( list->fn_head->first_name, str_key ) == 0 ) { // Bastan Silme Kosulu
if( num == counter ) {
list->fn_head->fn_next->fn_pre = list->fn_head;
list->fn_head = list->fn_head->fn_next;
free(list->fn_head);
printf("%s is deleted and the new header is %s\n", str_key, list->fn_head->first_name );
return;
}
counter++;
}
temp = temp->fn_next;
while ( temp->fn_next != NULL ) {
if( strcmp( temp->first_name, str_key ) == 0 ) {
if( num == counter ) {
temp->fn_pre->fn_next = temp->fn_next;
temp->fn_next->fn_pre = temp->fn_pre;
free(temp);
printf("%s deleted at between %s and %s\n", str_key, temp->fn_pre->first_name, temp->fn_next->first_name);
return;
}
counter++;
}
temp = temp->fn_next;
}
if( temp->fn_next == NULL ) { // Sondan Silme Kosulu
if( strcmp(temp->first_name, str_key) == 0 ) {
if( num == counter ) {
list->fn_tail = temp->fn_pre;
temp->fn_pre->fn_next = NULL;
free(temp);
printf("%s deleted at the end and new tail is %s \n", str_key, list->fn_tail->first_name );
return;
}
}
}
}
void del_ln_name(LIST* list, char* str_key) {
NODE* temp;
int num,counter=1,flag;
temp = list->ln_head;
if( list->ln_head == NULL ) {
printf("The list is EMPTY!!!\n");
return;
}
flag = search_ln(list,str_key);
if ( flag ) {
printf("Enter the number of student you want to delete : ");
scanf("%d", &num);
if( strcmp( list->ln_head->last_name, str_key ) == 0 ) { // Bastan Silme Kosulu
if( num == counter ) {
temp->ln_next->ln_pre = list->ln_head;
list->ln_head = temp->ln_next;
free(temp);
printf("%s is deleted and the new header is %s\n", str_key, list->ln_head->last_name );
return;
}
counter++;
}
temp = temp->ln_next;
while ( temp->ln_next != NULL ) {
if( strcmp( temp->last_name, str_key ) == 0 ) {
if( num == counter ) {
temp->ln_pre->ln_next = temp->ln_next;
temp->ln_next->ln_pre = temp->ln_pre;
free(temp);
printf("%s deleted at between %s and %s\n", str_key, temp->ln_pre->last_name, temp->ln_next->last_name);
return;
}
counter++;
}
temp = temp->ln_next;
}
if( temp->ln_next == NULL ) { // Sondan Silme Kosulu
printf("The last item %s second last item %s\n", temp->first_name, list->fn_tail->fn_pre->first_name);*/
if( strcmp(temp->last_name, str_key) == 0 ) {
if( num == counter ) {
list->ln_tail = temp->ln_pre;
temp->ln_pre->ln_next = NULL;
free(temp);
printf("%s deleted at the end and new tail is %s \n", str_key, list->ln_tail->last_name );
return;
}
}
}
}
整数flag 和counter 用于删除重复的学生。例如,如果有三个重复项,它会询问我要删除的学生人数。因此,如果我输入数字 2,它会删除第二个重复项。
【问题讨论】:
-
听起来您的列表将按其中一种指针类型排序;即名称,但您的姓氏指针会在您的列表中跳转。例如:
NameH -> 0 -> 1 -> 2 -> 3 - NULL,和Surname:H-> 2 -> 0 -> 3 -> 1 -> NULL。 -
是的,我说过我想要一个列表和两个不同的头指针。所以当然名字和姓氏会有不同的顺序。
-
是的,所以您可以在一种方法中添加所有内容;您只需先插入一个列表,然后重新排序第二个。
-
方法是我的问题。如何在一个函数中添加按名称和姓氏排序的节点?。
标签: c linked-list