学习的时候能将自己学到的东西写出来也是一种很好的学习方法,它既能加深学习的效果,又能知道自己对学习内容的了解情况。如果你写不出来也就说明你对所学的内容并不是完全了解,还有值得重新学习的地方。
本人大学只学习过一个学期的C语言,其他诸如数据结构与算法压根就没有学过,奈何毕业后从事的是与软件开发有关的工作,既然喜欢编程,这门课也只能自己自学啦。
数据结构学习中的第一个数据结构是线性表。分两种,一种是顺序表,一种是链表。
1. 顺序表——是在计算机内存中以数组形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。时间复杂度:插入O(n);查找特定节点O(logn);访问特定编号节点O(1);
2. 链表——非连续存储数据,在每个节点中,存储一个数据和指向下一个节点的指针。时间复杂度:插入O(1);查找特定节点O(n);访问特定编号节点O(n)。链表可以分为:单向链表,双向链表,循环链表三种。
3. 顺序表的数据结构:
/* 线性表的动态分配顺序存储结构 */ #define LIST_INIT_SIZE 100 /* 线性表存储空间的初始分配量 */ #define LIST_INCREMENT 10 /* 线性表存储空间的分配增量 */ typedef int ElemType; typedef int Status; typedef struct { ElemType *data; /* 存储空间基址 */ int length; /* 当前长度 */ int listsize; /* 当前分配的存储容量(以sizeof(ElemType)为单位) */ }SqList;
这里解释一下length和listsize的意思,打个比方,listsize就是水杯,length是水杯里的水,解释完毕。
4. 链表的数据结构:
typedef int ElemType; typedef int Status; typedef struct LNode { ElemType data; /* 数据部分 */ struct LNode *next; /* 用指针指向下一个数据存储的地址 */ }LNode, *LinkList;
5 . 线性表的基本操作:(以单链表为例,后续补充顺序表,双向链表和循环链表)
/* 线性表初始化 */ Status InitLinkList(LinkList &L) { L = (LinkList)malloc(sizeof(LNode)); /* 带有头结点的链表,分配空间 */ L->next = NULL; return OK; } /* 求线性表表长 */ int LinkListLength(LinkList L) { int i = 0; while(L->next != NULL) { i++; L = L->next; } return i; } /* 获得表中某个数据 */ void GetElem(LinkList L, int i, ElemType *e) { LinkList q = L; while(i) { q = q->next; i--; } (*e) = q->data; } /* 按某个数据查找表 */ int FindLinkList(LinkList L, ElemType e) { int i = 0; while(L->next != NULL) { if (L->data == e) return i; else { i++; L = L->next; } } return -1; } /* 插入操作 */ void InsertElem(LinkList L, int i, ElemType e) { LinkList p, q = L; while(i) { q = q->next; i--; } p = (LinkList)malloc(sizeof(LNode)); p->data = e; p->next = q->next; q->next = p; } /* 删除操作 */ void DeleteElem(LinkList L, ElemType e) { LinkList pre, cur = L; while(cur->next != NULL) { if (cur->data == e) { pre->next = cur->next; free(cur); break; } else { pre = cur; cur = cur->next; } } } /* 构造链表 */ void CreateLinkList(LinkList L, int n) { if (!L) InitLinkList(L); LinkList p, q = L; int data; cout << n << endl; for (int i = 0; i < n; i++) { p = (LinkList)malloc(sizeof(LNode)); scanf_s("%d", &data); p->data = data; p->next = q->next; q->next = p; q = p; } } /* 判断链表是否为空 */ Status LinkListEmpty(LinkList L) { return L->next == NULL; } /* 打印链表 */ void PrintLinkList(LinkList L) { LinkList q = L; q = q->next; while(q != NULL) { printf_s("%d\t", q->data); q = q->next; } printf_s("\n"); }
参考资料:
1. http://zh.wikipedia.org/wiki/%E9%A1%BA%E5%BA%8F%E8%A1%A8wikipedia顺序表
2. http://zh.wikipedia.org/wiki/%E5%8D%95%E9%93%BE%E8%A1%A8wikipedia单链表