一 链表
自己简单写了一个单链表,记录员工的名字和年龄:
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct employee
{
char name[10];
unsigned char age;
struct employee* next;
}Employee,*Employee_p;
Employee_p creat_employee_list(int cnt_number)
{
Employee_p one;
one = (Employee*)malloc(sizeof(Employee));
cin>>one->name;
cin>>one->age;
cnt_number = cnt_number - 1;
if(cnt_number == 0)
{
one->next = NULL;
}
else
{
one->next = creat_employee_list(cnt_number);
}
return one;
}
void display_employee_list(Employee_p first_employee)
{
while(1)
{
if(first_employee->next != NULL)
{
cout << first_employee->name << endl;
cout << first_employee->age << endl;
first_employee = first_employee->next;
}
else
{
cout << first_employee->name << endl;
cout << first_employee->age << endl;
break;
}
}
}
int main()
{
Employee_p one_employee;
one_employee = creat_employee_list(5);
display_employee_list(one_employee);
return 0;
}
在创建单链表是,我开始想到的就是利用结构体来完成,在创建过程中使用递归方法完成连接。
在编写时,出了点问题就是在显示链表数据时,总是最后一个现实不了,本来开始while(first_employee->next != NULL)来判断这样最后一个总是显示不了;后来没办法将最后一个利用if/else单独显示。今天和陈铭明交流,发现只要改动循环条件即可:while(first_employee != NULL)就能遍历到最后一个。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在上面的练习中,在写时一个链表节点就携带一个数据信息,这样没有一种归类的思想,即能不能将要写的所有数据信息用一个结构体表示,然后在链表节点中用一个指针指向携带的数据信息,还有一条链表写好后,关于这条链表我也用一个结构体来指向,表明链表头,链表尾。所以经过修改新的链表出来了:(此次修改中还用到了h文件,用以声明函数和变量)
main.cpp
#include<iostream>
#include<stdlib.h>
#include"std_link.h"
using namespace std;
int main()
{
Linklist* list = (Linklist*)malloc(sizeof(Linklist));
init_linklist(list);
add_to_linklist(add_node_employee(),list);
add_to_linklist(add_node_employee(),list);
add_to_linklist(add_node_employee(),list);
display_list(list);
return 0;
}
void init_linklist(Linklist* linklist)
{
linklist->head = NULL;
linklist->tail = NULL;
linklist->current = NULL;
}
Node* add_node_employee(void)
{
Employee *one_employee = (Employee*)malloc(sizeof(Employee));
cout<<"please input name and age"<<endl;
cin>>one_employee->name;
cin>>one_employee->age;
Node* one_node = (Node*)malloc(sizeof(Node));
one_node->info = one_employee;
one_node->next = NULL;
return one_node;
}
void add_to_linklist(Node* node,Linklist* list)
{
if(list->head == NULL)
{
list->head = node;
list->tail = node;
list->current = node;
}
else
{
list->tail->next = node;
list->tail = node;
list->current = node;
}
}
void display_list(Linklist* list)
{
Node* first = list->head;
Employee* employee;
while(first != NULL)
{
employee = (Employee*)first->info;
cout<<employee->name<<" "<<employee->age<<endl;
first = first->next;
}
}
main.h
#ifndef _STD_LINK_H_
#define _STD_LINK_H_
typedef struct _employee
{
char name[10];
unsigned int age;
}Employee;
typedef struct _node
{
void *info;
struct _node* next;
}Node;
typedef struct _linklist
{
Node* head;
Node* tail;
Node* current;
}Linklist;
extern void init_linklist(Linklist* linklist);
extern Node* add_node_employee(void);
extern void add_to_linklist(Node* node,Linklist* list);
extern void display_list(Linklist* list);
#endif
运行结果
-----------------------------------------------------------------------------------------------------------------------------------------------------
在上面的基础上又添加查找功能,添加了如下函数:
main.cpp
int compare_employee(Employee* e1,Employee* e2)
{
return strcmp(e1->name,e2->name);
}
Employee* name_for_seek()
{
Employee* one_name;
cout<<"please input name for seeking"<<endl;
cin>>one_name->name;
one_name->age = 1;
return one_name;
}
Node* seek_node(Linklist* list,Employee* name_for_seek,Compare compare)
{
Node* first = list->head;
Employee* employee;
while(first != NULL)
{
employee = (Employee*)first->info;
if(compare(employee->name,name_for_seek->name) == 0)
{
cout<<"find the guy"<<endl;
cout<<"name: "<<employee->name<<" age: "<<employee->age<<endl;
return first;
}
first = first->next;
}
}
main.h
typedef int (*Compare)(void* ,void* );
但是在调试时出现问题,
在调用完函数Employee* name_for_seek()之后没有返回,这是一个老问题,因为在函数中定义一个结构体是在栈里面的,一旦函数运行完,所分配的栈也就释放了,此时所指向的栈地址是非法的,在linux中应该是非法的。所以将之分配到堆中就可以了。
Employee* name_for_seek()
{
Employee* one_name = (Employee*)malloc(sizeof(Employee));
cout<<"please input name for seeking"<<endl;
cin>>one_name->name;
one_name->age = 1;
return one_name;
}
运行结果如下:
--------------------------------------------------------------------------------------------------------------------------------------------------
然后再添加一个任意delete一个链表元素,刚写完为:
void delete_node(Linklist* list,Employee* name_for_seek)
{
Node* node_for_delete;
node_for_delete = seek_node(list,name_for_seek(),(Compare)compare_employee);
Node* first = list->head;
Employee* employee;
if(first == node_for_delete)
{
list->head = first->next;
cout<<"ok delete the name"<<endl;
}
else
{
while(1)
{
if(first->next == node_for_delete)
{
first->next = node_for_delete->next;
break;
}
else if(first->next == NULL)
{
cout<<"sorry delete fail"<<endl;
break;
}
else
first = first->next;
}
}
}
g++ 编译报错为:
这里面是这样的name_for_seek在参数表中是一个指向Employee的指针,而在seek_node中却作为了函数指针。为了充分学习typedef的函数类型定义,完成了新的程序:
h文件
#ifndef _STD_LINK_H_
#define _STD_LINK_H_
typedef int (*Compare)(void* ,void* );
typedef struct _employee
{
char name[10];
unsigned int age;
}Employee;
typedef struct _node
{
void *info;
struct _node* next;
}Node;
typedef struct _linklist
{
Node* head;
Node* tail;
Node* current;
}Linklist;
typedef Node* (*Seeknode)(Linklist*,Employee*,Compare);
typedef Employee* (*Nameforseek)(void);
extern void init_linklist(Linklist* linklist);
extern Node* add_node_employee(void);
extern void add_to_linklist(Node* node,Linklist* list);
extern void display_list(Linklist* list);
extern int compare_employee(Employee* e1,Employee* e2);
extern Node* seek_node(Linklist* list,Employee* name_for_seek,Compare compare);
extern Employee* name_for_seek(void);
extern void delete_node(Linklist* list,Seeknode seeknode,Nameforseek nameforseek,Compare compare);
#endif
main文件
#include<iostream>
#include<stdlib.h>
#include"std_link.h"
using namespace std;
int main()
{
Linklist* list = (Linklist*)malloc(sizeof(Linklist));
init_linklist(list);
add_to_linklist(add_node_employee(),list);
add_to_linklist(add_node_employee(),list);
add_to_linklist(add_node_employee(),list);
display_list(list);
seek_node(list,name_for_seek(),(Compare)compare_employee);
delete_node(list,(Seeknode)seek_node,(Nameforseek)name_for_seek,(Compare)compare_employee);
display_list(list);
return 0;
}
void init_linklist(Linklist* linklist)
{
linklist->head = NULL;
linklist->tail = NULL;
linklist->current = NULL;
}
Node* add_node_employee(void)
{
Employee *one_employee = (Employee*)malloc(sizeof(Employee));
cout<<"please input name and age"<<endl;
cin>>one_employee->name;
cin>>one_employee->age;
Node* one_node = (Node*)malloc(sizeof(Node));
one_node->info = one_employee;
one_node->next = NULL;
return one_node;
}
void add_to_linklist(Node* node,Linklist* list)
{
if(list->head == NULL)
{
list->head = node;
list->tail = node;
list->current = node;
}
else
{
list->tail->next = node;
list->tail = node;
list->current = node;
}
}
void display_list(Linklist* list)
{
Node* first = list->head;
Employee* employee;
cout<<"display all list "<<endl;
while(first != NULL)
{
employee = (Employee*)first->info;
cout<<employee->name<<" "<<employee->age<<endl;
first = first->next;
}
}
int compare_employee(Employee* e1,Employee* e2)
{
return strcmp(e1->name,e2->name);
}
Employee* name_for_seek(void)
{
Employee* one_name = (Employee*)malloc(sizeof(Employee));
cout<<"please input name for seeking"<<endl;
cin>>one_name->name;
one_name->age = 1;
return one_name;
}
Node* seek_node(Linklist* list,Employee* name_for_seek,Compare compare)
{
Node* first = list->head;
Employee* employee;
while(first != NULL)
{
employee = (Employee*)first->info;
if(compare(employee->name,name_for_seek->name) == 0)
{
cout<<"find the guy"<<endl;
cout<<"name: "<<employee->name<<" age: "<<employee->age<<endl;
return first;
}
first = first->next;
}
cout<<"sorry AI can not find your name"<<endl;
}
void delete_node(Linklist* list,Seeknode seeknode,Nameforseek nameforseek,Compare compare)
{
Node* node_for_delete;
cout<<"delete one name:"<<endl;
node_for_delete = seeknode(list,nameforseek(),compare);
Node* first = list->head;
if(first == node_for_delete)
{
list->head = first->next;
cout<<"ok delete the name"<<endl;
}
else
{
while(1)
{
if(first->next == node_for_delete)
{
first->next = node_for_delete->next;
break;
}
else if(first->next == NULL)
{
cout<<"sorry delete fail"<<endl;
break;
}
else
first = first->next;
}
}
}
在编写上面时遇到了一些基本错误:
typedef Node* (*Seeknode)(Linklist*,Employee*,Compare);
typedef Employee* (*Nameforseek)(void);
typedef int (*Compare)(void* ,void* );
类似于这样的定义顺序,这是编译不懂过的,当然十年后可能通过。
还有一个问题就是,看了代码会发现,我错误的认为,只有main函数可以直接调用其他函数,而其他函数之间的调用必须通过参数传递,不是的,只要函数的使用范围允许即可(有机会会再研究这个问题),简化程序如下:
void delete_node(Linklist* list)//Seeknode seeknode,Nameforseek nameforseek,Compare compare)
{
Node* node_for_delete;
cout<<"delete one name:"<<endl;
node_for_delete = seek_node(list,name_for_seek(),(Compare)compare_employee);
Node* first = list->head;
if(first == node_for_delete)
{
list->head = first->next;
cout<<"ok delete the name"<<endl;
}
else
{
while(1)
{
if(first->next == node_for_delete)
{
first->next = node_for_delete->next;
break;
}
else if(first->next == NULL)
{
cout<<"sorry delete fail"<<endl;
break;
}
else
first = first->next;
}
}
}
运行结果:
(有机会再补充)