数据结构——链表
2016-03-03 16:24
483 查看
学数据结构之前按照自己的理解写的链表模板,不好勿喷。图省事就把所有的函数写在了类里面,这不是个好的做法
接下来是双向链表的模板
以下为2016.4.8编辑:
贴一个数据结构作业的代码,双向链表,纯C。
/*
* List.h
*
* Created on: 2016年3月28日
* Author: Triose
*/
#ifndef LIST_H_
#define LIST_H_
#include<stdlib.h>
#include"Book.h"
typedef struct ListElmt_ {
void *data;
struct ListElmt_ *next;
struct ListElmt_ *prev;
}ListElmt;
#define pfElmt(current_elmt) (printf("%s\t%s\t%lf\n", ((Book*)(current_elmt->data))->ISBN, ((Book*)(current_elmt->data))->name, ((Book*)(current_elmt->data))->price))
#define pfElmt_to_file(current_elmt, fptr_out) (fprintf(fptr_out, "%s\t%s\t%lf\n", ((Book*)(current_elmt->data))->ISBN, ((Book*)(current_elmt->data))->name, ((Book*)(current_elmt->data))->price))
/* Public Interface. */
ListElmt * new_Elmt(const void *data_) {
ListElmt * newelement = (ListElmt *) malloc (sizeof(ListElmt));
newelement->data = (void *)data_;
newelement->prev = NULL;
newelement->next = NULL;
return newelement;
}
typedef struct List_ {
ListElmt * head;
ListElmt * tail;
int size;
}List;
/* Public Interface. */
#define List_size(list) ((list)->size)
#define List_head(list) ((list)->head)
#define List_tail(list) ((list)->tail)
/* List_init. */
void List_init(List * list) {
list->head = NULL;
list->tail = NULL;
list->size = 0;
}
/* List_ins. */
int List_ins(List * list, ListElmt * newelement, int pos) {
pos--;
if(pos < 0 || pos > list->size) {
return -1;
}
if(pos && !list->size) {
return -1;
}
if(!pos) {
newelement->next = list->head;
if(list->head) { //如果list->head != NULL 证明不是空表,至少有一个元素
list->head->prev = newelement;
}
else { //否则就是空表,只需让尾指针也指向newelement即可
list->tail = newelement;
}
list->head = newelement; //头指针指向插入表头的节点
list->size++; //维护表长
return 0; //正确返回
}
ListElmt * current_elmt = list->head;
int index = 0;
while(current_elmt->next && index < pos - 1) {
index++;
current_elmt = current_elmt->next;
}
if(index == pos - 1) { //此时current_elmt指向插入位置的前一个元素
// current_elmt->next = newelement;
newelement->next = current_elmt->next;
newelement->prev = current_elmt;
if(current_elmt->next) { //如果current_elmt->next != NULL 那么current_elmt不是表尾元素
current_elmt->next->prev = newelement;
}
else { //current_elmt是表尾元素
list->tail = newelement;
}
current_elmt->next = newelement;
list->size++; //维护表长
return 0; //正确返回
}
return -1; //除所有限定正确情况之外全都是不正确
}
/* List_rem. */
int List_rem(List * list, int pos) {
pos--;
if(!list->size) { //空表
return -1;
}
if(pos < 0 || pos >= list->size) { //位置不正确
return -1;
}
if(!pos) { //删除头结点
ListElmt *delete_elmt = list->head;
list->head = list->head->next; //头指针指向第一个元素
if(list->head) { //如果第一个元素不是空,即删除第0个元素之后链表还有元素
list->head->prev = NULL; //把现在的头结点的前指针置空
}
else { //否则,即链表之有要删除的一个元素,那么把链表尾指针也置空
list->tail = NULL;
}
free(delete_elmt); //删除待删除元素
list->size--;
return 0; //返回正确
}
ListElmt *current_elmt = list->head;
int index = 0;
while(current_elmt->next && index < pos - 1) { //遍历,令current_elmt指向被删除的前一个元素
current_elmt = current_elmt->next;
index++;
}
if(index == pos - 1) {
ListElmt *delete_elmt = current_elmt->next;
current_elmt->next = current_elmt->next->next;
if(current_elmt->next) { //同理
current_elmt->next->prev = current_elmt;
}
else {
list->tail = current_elmt;
}
free(delete_elmt);
list->size--;
return 0;
}
return -1; //所有非限定情况全部返回错误
}
/* List_Inverse. */
void List_Inverse(List * list) {
if(!list->size || list->size == 0) { //空表或者单元素表直接返回
return ;
}
/* 至少有两个元素. */
ListElmt * current_elmt = list->head;
ListElmt * next_elmt = current_elmt->next;
int index = 0;
while(index < list->size - 2) { //交换前后指针
ListElmt * tmp_elmt = next_elmt->next;
next_elmt->prev = tmp_elmt;
next_elmt->next = current_elmt;
current_elmt = next_elmt;
next_elmt = tmp_elmt;
index++;
}
list->head->prev = list->head->next; //处理头尾指针和指向
list->head->next = NULL;
list->tail->next = list->tail->prev;
list->tail->prev = NULL;
ListElmt *tmp_elmt = list->head;
list->head = list->tail;
list->tail = tmp_elmt;
return ;
}
/* List_get_elmt. */
ListElmt * List_get_elmt(List * list, int pos) {
pos--;
if(pos < 0 || pos >= list->size){
return NULL;
}
ListElmt * current_elmt = list->head;
int index = 0;
while(index < pos) {
index++;
current_elmt = current_elmt->next;
}
return current_elmt;
}
/*****************************************************************************
* 链表的快速排序采用快排并不是最优方案(对,我亲身实践了,因为指针的确会乱而且不止是交换数据那么简单,所以我放弃采用快排而自学了归并)
* c++ list头文件里默认排序是堆排序。
* 这三个函数是我读了list头文件里的_Sort函数写出来的。
* 毕竟这不是工业级代码。。。所以可能会有Bug
*****************************************************************************/
int cmp(const ListElmt * u, const ListElmt * v) { //用于归并排序的比较函数
return (((Book *)u->data)->price > ((Book *)v->data)->price ? 1 : 0);
}
ListElmt * get_mid(ListElmt * start, int lenth) { //给定头结点,找出中间节点的函数
int mid = 1;
ListElmt * current_elmt = start;
while(mid < lenth ) {
mid++;
current_elmt = current_elmt->next;
}
return current_elmt;
}
void cut_down(ListElmt * elmt, int len) { //切断指向范围之外的指针,主要是头结点的prev指针和尾结点的next指针
ListElmt * current_elmt = elmt;
current_elmt->prev = NULL;
int i = 1;
while(i < len) {
i++;
current_elmt = current_elmt->next;
}
current_elmt->next = NULL;
}
ListElmt * merge(ListElmt * u, ListElmt * v, int (*cmp)(const ListElmt *u, const ListElmt *v), int uLen, int vLen) {
/*这个函数用来归并两段链表,两段链表的头结点分别是u和v. */
cut_down(u, uLen); //为了避免死循环,必须切断指向这两段链表范围之外的指针
cut_down(v, vLen);
int i = 0,
j = 0;
ListElmt * _newstart = v; //先把v作为合并后的头结点
if(cmp(u, v)) { //如果u比v大(这里以由降序为例),则合并后的头节点为u
_newstart = u;
}
ListElmt * index = 0; //用来连接各个节点的指针
while(i < uLen && j < vLen) { //合并过程,连接各个指针
if(cmp(u,v)) {
if(!index) {
index = u;
}
else {
index->next = u;
u->prev = index;
index = index->next;
}
i++;
if(i == uLen) {
index->next = v;
v->prev = index;
}
u = u->next;
}
else {
if(!index) {
index = v;
}
else {
index->next = v;
v->prev = index;
index = index->next;
}
j++;
if(j == vLen) {
index->next = u;
u->prev = index;
}
v = v->next;
}
}
return _newstart;
}
ListElmt * merge_sort(List * list, ListElmt * start, ListElmt * end, int (*cmp)(const ListElmt *u, const ListElmt *v), int lenth) {
if(lenth < 2) { //只剩一个元素的时候,直接return就好
return start;
}
int uLen = lenth / 2 + (lenth % 2); //二分的两部分的长度
int vLen = lenth - uLen;
ListElmt * mid = get_mid(start, uLen); //二分之前首先得找到中间的元素
ListElmt * _newstart = merge(merge_sort(list, start, mid, cmp, uLen), merge_sort(list, mid->next, end, cmp, vLen), cmp, uLen, vLen);
list->head = _newstart; //更新原链表的头结点和尾结点(这段比较啰嗦)
ListElmt * current_elmt = list->head;
while(current_elmt->next) {
current_elmt = current_elmt->next;
}
list->tail = current_elmt;
return _newstart;
}
void find_name(List *list, char * name_) {
ListElmt * current_elmt = list->head;
int index = 0;
while(current_elmt) { //遍历链表,所有重名的书全部输出
if(strcmp(((Book *)current_elmt->data)->name, name_) == 0) {
index = 1;
printf("%s\t%s\t%lf\n", ((Book *)current_elmt->data)->ISBN, ((Book *)current_elmt->data)->name, ((Book *)current_elmt->data)->price);
}
current_elmt = current_elmt->next;
}
if(!index) {
printf("找不到名字为:%s的书\n", name_);
}
return ;
}
void find_ISBN(List *list, char * isbn_) {
ListElmt * current_elmt = list->head;
int index = 0;
while(current_elmt) { //遍历链表,所有ISBN相同的全部输出(不排除有相同的ISBN)
if(strcmp(((Book *)current_elmt->data)->ISBN, isbn_) == 0) {
index = 1;
printf("%s\t%s\t%lf\n", ((Book *)current_elmt->data)->ISBN, ((Book *)current_elmt->data)->name, ((Book *)current_elmt->data)->price);
}
current_elmt = current_elmt->next;
}
if(!index) {
printf("找不到标号为:%s的书\n", isbn_);
}
return ;
}
/* List_destroy. */
void List_destroy(List * list) { //析构函数,移除所有节点
while(list->size) {
List_rem(list, 1);
}
}
#endif /* LIST_H_ */
/* * My_list.h * * Created on: 2016年2月3日 * Author: triose */ #include<iostream> using namespace std; #ifndef MY_LIST_H_ #define MY_LIST_H_ /* Define of elements */ template <class T> class ListElmt { public: T data; ListElmt * next; ListElmt(T data_) { data = data_; next = NULL; } }; /* Define of My_list */ template <class T> class My_list { private : int size; ListElmt<T> *head; ListElmt<T> *tail; public : My_list() { //构造函数 size = 0; head = NULL; tail = NULL; } ~My_list() { //析构函数,移除并删除每个结点(删除操作在移除函数里就已完成) this->delete_all(); } void ins_next(ListElmt<T> *element, int pos) { //插入函数,把element插入到第pos个结点的后面 if(size == 0) { //空表的情况 head = element; tail = element; size ++; return ; } if(pos == -1 ) { //插入表头 element->next = head; head = element; size ++; return ; } ListElmt<T> *current_elmt = head; //插入表中 int index = 0; while(current_elmt->next != NULL && index < pos) { index ++; current_elmt = current_elmt->next; } if(index == pos) { element->next = current_elmt->next; current_elmt->next = element; if(pos == size - 1) { tail = element; } size++; return ; } } ListElmt<T> * rem_next(int pos) { //移除函数,移除并返回pos位置之后的结点 ListElmt<T> * re_element = head; ListElmt<T> * delete_element = head; if(size == 0) { //空表,操作失败 return NULL; } if(pos == -1) { //移除表头元素 head = head->next; size--; delete delete_element; return re_element; } ListElmt<T> *current_elmt = head; //移除其他位置元素 int index = 0; while(current_elmt->next != NULL && index < pos) { index++; current_elmt = current_elmt->next; } if(index == pos) { re_element = current_elmt->next; delete_element = current_elmt->next; current_elmt->next = current_elmt->next->next; if(pos == size - 2) { tail = current_elmt; } delete delete_element; size--; } return re_element; } void delete_all() { //移除所有元素 while(size > 0) { this->rem_next(-1); } } void output(){ /* For debug */ ListElmt<T> * current_elmt = head; int index = 0; while((index++) < size) { cout << current_elmt->data << ' '; current_elmt = current_elmt->next; } cout << endl; cout << "tou:\n" << head->data << endl; cout << "wei:\n" << tail->data << endl; cout << "size:\n" << size << endl; } }; #endif /* MY_LIST_H_ */
接下来是双向链表的模板
/* * DList.h * * Created on: 2016年2月3日 * Author: triose */ #ifndef DLIST_H_ #define DLIST_H_ #include <iostream> using namespace std; template <class T> class DListElmt { public: T data; DListElmt * prev; DListElmt * next; DListElmt(T data_) { data = data_; prev = NULL; next = NULL; } }; template <class T> class DList { private: DListElmt<T> *head; DListElmt<T> *tail; int size; public: DList() { head = NULL ; tail = NULL; size = 0; } ~DList() { if(size) delete_all(); } /* public Interface*/ void ins_next(DListElmt<T> * element, int pos) { if(size == 0) { head = element; tail = element; size++; return ; } if(pos == -1) { element->next = head; head->prev = element; head = element; size++; return ; } DListElmt<T> *current_elmt = head; int index = 0; while(current_elmt->next != NULL && index < pos) { index++; current_elmt = current_elmt->next; } if(index == pos) { element->prev = current_elmt; element->next = current_elmt->next; current_elmt->next = element; if(current_elmt->next->next != NULL) { current_elmt->next->next->prev = element; } if(pos == size - 1) { tail = element; } size++; return ; } } DListElmt<T> *rem_next(int pos) { DListElmt<T> * re_element = head; DListElmt<T> * delete_elmt = head; if(size == 0) { return NULL; } if(pos == -1) { head = head->next; delete delete_elmt; size--; return re_element; } DListElmt<T> * current_elmt = head; int index = 0; while(current_elmt->next != NULL && index < pos) { current_elmt = current_elmt->next; index++; } if(index == pos) { delete_elmt = current_elmt->next; re_element = current_elmt->next; current_elmt->next = current_elmt->next->next; if(current_elmt->next != NULL) current_elmt->next->prev = current_elmt; if(pos == size - 2) { tail = current_elmt; } size--; } return re_element; } void delete_all() { while(size > 0) { this->rem_next(-1); } } void output() { /*For debug*/ cout << "从前往后:" << endl; DListElmt<T> * current_elmt = head; for(int i = 0; i < size; i++) { cout << current_elmt->data << " " ; current_elmt = current_elmt->next; } cout << endl; cout << "从后往前:" << endl; current_elmt = tail; for(int i = 0; i < size; i++) { cout << current_elmt->data << " "; current_elmt = current_elmt->prev; } cout << endl; cout << "head : " << endl; cout << head->data << endl; cout << "tail : " << endl; cout << tail->data << endl; cout << "size : " << endl; cout << size << endl; } }; #endif /* DLIST_H_ */
以下为2016.4.8编辑:
贴一个数据结构作业的代码,双向链表,纯C。
/*
* List.h
*
* Created on: 2016年3月28日
* Author: Triose
*/
#ifndef LIST_H_
#define LIST_H_
#include<stdlib.h>
#include"Book.h"
typedef struct ListElmt_ {
void *data;
struct ListElmt_ *next;
struct ListElmt_ *prev;
}ListElmt;
#define pfElmt(current_elmt) (printf("%s\t%s\t%lf\n", ((Book*)(current_elmt->data))->ISBN, ((Book*)(current_elmt->data))->name, ((Book*)(current_elmt->data))->price))
#define pfElmt_to_file(current_elmt, fptr_out) (fprintf(fptr_out, "%s\t%s\t%lf\n", ((Book*)(current_elmt->data))->ISBN, ((Book*)(current_elmt->data))->name, ((Book*)(current_elmt->data))->price))
/* Public Interface. */
ListElmt * new_Elmt(const void *data_) {
ListElmt * newelement = (ListElmt *) malloc (sizeof(ListElmt));
newelement->data = (void *)data_;
newelement->prev = NULL;
newelement->next = NULL;
return newelement;
}
typedef struct List_ {
ListElmt * head;
ListElmt * tail;
int size;
}List;
/* Public Interface. */
#define List_size(list) ((list)->size)
#define List_head(list) ((list)->head)
#define List_tail(list) ((list)->tail)
/* List_init. */
void List_init(List * list) {
list->head = NULL;
list->tail = NULL;
list->size = 0;
}
/* List_ins. */
int List_ins(List * list, ListElmt * newelement, int pos) {
pos--;
if(pos < 0 || pos > list->size) {
return -1;
}
if(pos && !list->size) {
return -1;
}
if(!pos) {
newelement->next = list->head;
if(list->head) { //如果list->head != NULL 证明不是空表,至少有一个元素
list->head->prev = newelement;
}
else { //否则就是空表,只需让尾指针也指向newelement即可
list->tail = newelement;
}
list->head = newelement; //头指针指向插入表头的节点
list->size++; //维护表长
return 0; //正确返回
}
ListElmt * current_elmt = list->head;
int index = 0;
while(current_elmt->next && index < pos - 1) {
index++;
current_elmt = current_elmt->next;
}
if(index == pos - 1) { //此时current_elmt指向插入位置的前一个元素
// current_elmt->next = newelement;
newelement->next = current_elmt->next;
newelement->prev = current_elmt;
if(current_elmt->next) { //如果current_elmt->next != NULL 那么current_elmt不是表尾元素
current_elmt->next->prev = newelement;
}
else { //current_elmt是表尾元素
list->tail = newelement;
}
current_elmt->next = newelement;
list->size++; //维护表长
return 0; //正确返回
}
return -1; //除所有限定正确情况之外全都是不正确
}
/* List_rem. */
int List_rem(List * list, int pos) {
pos--;
if(!list->size) { //空表
return -1;
}
if(pos < 0 || pos >= list->size) { //位置不正确
return -1;
}
if(!pos) { //删除头结点
ListElmt *delete_elmt = list->head;
list->head = list->head->next; //头指针指向第一个元素
if(list->head) { //如果第一个元素不是空,即删除第0个元素之后链表还有元素
list->head->prev = NULL; //把现在的头结点的前指针置空
}
else { //否则,即链表之有要删除的一个元素,那么把链表尾指针也置空
list->tail = NULL;
}
free(delete_elmt); //删除待删除元素
list->size--;
return 0; //返回正确
}
ListElmt *current_elmt = list->head;
int index = 0;
while(current_elmt->next && index < pos - 1) { //遍历,令current_elmt指向被删除的前一个元素
current_elmt = current_elmt->next;
index++;
}
if(index == pos - 1) {
ListElmt *delete_elmt = current_elmt->next;
current_elmt->next = current_elmt->next->next;
if(current_elmt->next) { //同理
current_elmt->next->prev = current_elmt;
}
else {
list->tail = current_elmt;
}
free(delete_elmt);
list->size--;
return 0;
}
return -1; //所有非限定情况全部返回错误
}
/* List_Inverse. */
void List_Inverse(List * list) {
if(!list->size || list->size == 0) { //空表或者单元素表直接返回
return ;
}
/* 至少有两个元素. */
ListElmt * current_elmt = list->head;
ListElmt * next_elmt = current_elmt->next;
int index = 0;
while(index < list->size - 2) { //交换前后指针
ListElmt * tmp_elmt = next_elmt->next;
next_elmt->prev = tmp_elmt;
next_elmt->next = current_elmt;
current_elmt = next_elmt;
next_elmt = tmp_elmt;
index++;
}
list->head->prev = list->head->next; //处理头尾指针和指向
list->head->next = NULL;
list->tail->next = list->tail->prev;
list->tail->prev = NULL;
ListElmt *tmp_elmt = list->head;
list->head = list->tail;
list->tail = tmp_elmt;
return ;
}
/* List_get_elmt. */
ListElmt * List_get_elmt(List * list, int pos) {
pos--;
if(pos < 0 || pos >= list->size){
return NULL;
}
ListElmt * current_elmt = list->head;
int index = 0;
while(index < pos) {
index++;
current_elmt = current_elmt->next;
}
return current_elmt;
}
/*****************************************************************************
* 链表的快速排序采用快排并不是最优方案(对,我亲身实践了,因为指针的确会乱而且不止是交换数据那么简单,所以我放弃采用快排而自学了归并)
* c++ list头文件里默认排序是堆排序。
* 这三个函数是我读了list头文件里的_Sort函数写出来的。
* 毕竟这不是工业级代码。。。所以可能会有Bug
*****************************************************************************/
int cmp(const ListElmt * u, const ListElmt * v) { //用于归并排序的比较函数
return (((Book *)u->data)->price > ((Book *)v->data)->price ? 1 : 0);
}
ListElmt * get_mid(ListElmt * start, int lenth) { //给定头结点,找出中间节点的函数
int mid = 1;
ListElmt * current_elmt = start;
while(mid < lenth ) {
mid++;
current_elmt = current_elmt->next;
}
return current_elmt;
}
void cut_down(ListElmt * elmt, int len) { //切断指向范围之外的指针,主要是头结点的prev指针和尾结点的next指针
ListElmt * current_elmt = elmt;
current_elmt->prev = NULL;
int i = 1;
while(i < len) {
i++;
current_elmt = current_elmt->next;
}
current_elmt->next = NULL;
}
ListElmt * merge(ListElmt * u, ListElmt * v, int (*cmp)(const ListElmt *u, const ListElmt *v), int uLen, int vLen) {
/*这个函数用来归并两段链表,两段链表的头结点分别是u和v. */
cut_down(u, uLen); //为了避免死循环,必须切断指向这两段链表范围之外的指针
cut_down(v, vLen);
int i = 0,
j = 0;
ListElmt * _newstart = v; //先把v作为合并后的头结点
if(cmp(u, v)) { //如果u比v大(这里以由降序为例),则合并后的头节点为u
_newstart = u;
}
ListElmt * index = 0; //用来连接各个节点的指针
while(i < uLen && j < vLen) { //合并过程,连接各个指针
if(cmp(u,v)) {
if(!index) {
index = u;
}
else {
index->next = u;
u->prev = index;
index = index->next;
}
i++;
if(i == uLen) {
index->next = v;
v->prev = index;
}
u = u->next;
}
else {
if(!index) {
index = v;
}
else {
index->next = v;
v->prev = index;
index = index->next;
}
j++;
if(j == vLen) {
index->next = u;
u->prev = index;
}
v = v->next;
}
}
return _newstart;
}
ListElmt * merge_sort(List * list, ListElmt * start, ListElmt * end, int (*cmp)(const ListElmt *u, const ListElmt *v), int lenth) {
if(lenth < 2) { //只剩一个元素的时候,直接return就好
return start;
}
int uLen = lenth / 2 + (lenth % 2); //二分的两部分的长度
int vLen = lenth - uLen;
ListElmt * mid = get_mid(start, uLen); //二分之前首先得找到中间的元素
ListElmt * _newstart = merge(merge_sort(list, start, mid, cmp, uLen), merge_sort(list, mid->next, end, cmp, vLen), cmp, uLen, vLen);
list->head = _newstart; //更新原链表的头结点和尾结点(这段比较啰嗦)
ListElmt * current_elmt = list->head;
while(current_elmt->next) {
current_elmt = current_elmt->next;
}
list->tail = current_elmt;
return _newstart;
}
void find_name(List *list, char * name_) {
ListElmt * current_elmt = list->head;
int index = 0;
while(current_elmt) { //遍历链表,所有重名的书全部输出
if(strcmp(((Book *)current_elmt->data)->name, name_) == 0) {
index = 1;
printf("%s\t%s\t%lf\n", ((Book *)current_elmt->data)->ISBN, ((Book *)current_elmt->data)->name, ((Book *)current_elmt->data)->price);
}
current_elmt = current_elmt->next;
}
if(!index) {
printf("找不到名字为:%s的书\n", name_);
}
return ;
}
void find_ISBN(List *list, char * isbn_) {
ListElmt * current_elmt = list->head;
int index = 0;
while(current_elmt) { //遍历链表,所有ISBN相同的全部输出(不排除有相同的ISBN)
if(strcmp(((Book *)current_elmt->data)->ISBN, isbn_) == 0) {
index = 1;
printf("%s\t%s\t%lf\n", ((Book *)current_elmt->data)->ISBN, ((Book *)current_elmt->data)->name, ((Book *)current_elmt->data)->price);
}
current_elmt = current_elmt->next;
}
if(!index) {
printf("找不到标号为:%s的书\n", isbn_);
}
return ;
}
/* List_destroy. */
void List_destroy(List * list) { //析构函数,移除所有节点
while(list->size) {
List_rem(list, 1);
}
}
#endif /* LIST_H_ */
相关文章推荐
- 数据结构常见面试(1)
- 数据结构——线性表的学习
- 数据结构,
- 数据结构-有头双向循环链表2(封装)
- 数据结构-有头双向循环链表
- 常用集合的底层数据结构和实现-Map
- 1-4-2 Windows数据类型与重要数据结构
- 3.4 IplImage数据结构
- 6-4-线索二叉树-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版
- NameNode启动过程详细剖析 NameNode中几个关键的数据结构 FSImage
- 网易云课堂-陈越、何钦铭-数据结构-2016春,学习笔记,1.3 应用实例:最大子列和问题
- c语言实现tree数据结构
- 数据与数据结构
- 数据结构-BST、AVL、二叉堆、B树、B+树、红黑树
- 数据结构学习之栈篇
- 《数据结构》单链表反转
- 插入类排序----直接插入排序
- 关于冒泡排序算法的初学错误认识
- 排序算法之简单选择排序
- vector<bool>STL中的陷阱