学习的时候能将自己学到的东西写出来也是一种很好的学习方法,它既能加深学习的效果,又能知道自己对学习内容的了解情况。如果你写不出来也就说明你对所学的内容并不是完全了解,还有值得重新学习的地方。
本人大学只学习过一个学期的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单链表