利用C指针编写自己的一些数据结构(链表)
2014-10-23 21:50
281 查看
一 链表
自己简单写了一个单链表,记录员工的名字和年龄:
在创建单链表是,我开始想到的就是利用结构体来完成,在创建过程中使用递归方法完成连接。
在编写时,出了点问题就是在显示链表数据时,总是最后一个现实不了,本来开始while(first_employee->next != NULL)来判断这样最后一个总是显示不了;后来没办法将最后一个利用if/else单独显示。今天和陈铭明交流,发现只要改动循环条件即可:while(first_employee != NULL)就能遍历到最后一个。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
在上面的练习中,在写时一个链表节点就携带一个数据信息,这样没有一种归类的思想,即能不能将要写的所有数据信息用一个结构体表示,然后在链表节点中用一个指针指向携带的数据信息,还有一条链表写好后,关于这条链表我也用一个结构体来指向,表明链表头,链表尾。所以经过修改新的链表出来了:(此次修改中还用到了h文件,用以声明函数和变量)
main.cpp
main.h
运行结果
-----------------------------------------------------------------------------------------------------------------------------------------------------
在上面的基础上又添加查找功能,添加了如下函数:
main.cpp
main.h
但是在调试时出现问题,
在调用完函数Employee* name_for_seek()之后没有返回,这是一个老问题,因为在函数中定义一个结构体是在栈里面的,一旦函数运行完,所分配的栈也就释放了,此时所指向的栈地址是非法的,在linux中应该是非法的。所以将之分配到堆中就可以了。
运行结果如下:
--------------------------------------------------------------------------------------------------------------------------------------------------
然后再添加一个任意delete一个链表元素,刚写完为:
g++ 编译报错为:
这里面是这样的name_for_seek在参数表中是一个指向Employee的指针,而在seek_node中却作为了函数指针。为了充分学习typedef的函数类型定义,完成了新的程序:
h文件
main文件
在编写上面时遇到了一些基本错误:
typedef Node* (*Seeknode)(Linklist*,Employee*,Compare);
typedef Employee* (*Nameforseek)(void);
typedef int (*Compare)(void* ,void* );
类似于这样的定义顺序,这是编译不懂过的,当然十年后可能通过。
还有一个问题就是,看了代码会发现,我错误的认为,只有main函数可以直接调用其他函数,而其他函数之间的调用必须通过参数传递,不是的,只要函数的使用范围允许即可(有机会会再研究这个问题),简化程序如下:
运行结果:
(有机会再补充)
自己简单写了一个单链表,记录员工的名字和年龄:
#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; } } }
运行结果:
(有机会再补充)
相关文章推荐
- 利用C指针编写自己的一些数据结构(树)
- 要完整准确的 均以单链表作存储结构 试编写算法将A表和B表归并成一个按元素值递减有序的线性表C 【数据结构】假设有两个按元素值递增有序的线性表A和B 并要求利用原表的空间存放C。谁会么
- uva133 利用指针编写双向循环链表
- 自学习指针后,自己利用指针编写判断三个数的大小。
- 利用C#的指针编写都一个简单链表
- 数据结构与算法:单链表(利用万能指针实现对任意类型数据进行操作)
- 利用pcap编写自己的sniffer程序
- 利用模板类编写一个程序,实现双向链表的插入、删除、查找、显示的功能。
- 在Delphi中编写自己的链表管理类。 推荐
- 如何在利用CSharp球队模板编写自己的足球队
- C++编写利用数据结构中队列(Queue)打印出用户所指定长度的杨辉三角
- SQL效率提升之一些SQL编写建议并有效利用索引
- SQL效率提升之一些SQL编写建议并有效利用索引
- 利用Recognizer编写自己的开机自启动程序
- 数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)
- 自己写的 利用指针写的有关学生成绩系统!欢迎赐教,给些建议2012-2-12---2012-2-14
- 最近在利用DSP做一个项目,好久没来自己的空间了,后续有时间会发一些自己的学习经验,呵呵!
- 如何编写自己的缓冲区溢出利用程序
- 这是我参考网上编写的一道数据结构关于二叉树求其子树是否指针或者线索,及其对应得值,但是我运行结果却是有点问题,希望高手帮指教下!
- 利用Recognizer编写自己的开机自启动程序