文章目录
1:ADT:把具体问题抽象化,抽象成一般问题
3:存取的意思:
4:单链表:每个节点(Node)只包含一个指针域
头结点与头指针
5: 空链表:^ 代表NULL
6:单链表(Singly Linked List)的操作:
插入的时候保持有序(升序)
void List ::insert(ElemType val)
{
LinkNode *p1, *p2, *q;
q = new LinkNode(val);
p2 = first->link;
p1 = first;
while (p2 != NULL)
if (p2->data < val)
{
p1 = p2;
p2 = p2->link; //此时等价于 p1->next = p2
}
else if(p2->data > val)
{
q->link = p2;
p1->link = q;
break;
}
if (p2 == NULL) //此时代表 整个list的所有node 都小于val
p1->link = q; //此时p1代表当前 未插入的list 的last node
}
删除一个特定节点: 俩个工作指针 p1,p2
void delete(del_val)
{
int cnt = 0;
LinkNode *p1 = Head;
LinkNode *p2 = Head->next; //头node, 不是链表的first node
while(p2 != NULL)
{
if(p2->data == val)
{
p1->next = p2->next;
delete p2;
cnt++;
}
p2 = p1->next;
}
if(p2 == NULL)
cout<<"删除的元素不存在"<<endl;
else if(p2 != NULL)
{
p1->next = p2->next; //即使是list's first node->data==val, 此时p1==Head, 正好Head->next = p2->next(删去了p2)
}
}
转置: 三个工作指针 p1,p2,p3
void List::reverse()
{
LinkNode *p1, *p2, *p3;
p1 = first->link;
if (p1 != NULL)
{
p2 = p1->link;
p1->link = NULL;
while (p2 != NULL)
{
p3 = p2->link;
p2->link = p1;
p1 = p2;
p2 = p3;
}
first->link = p1; //此时p1是 转置前的链表的 最后一个node
}
}
7:单链表结构与顺序存储结构(比如数组)优缺点:
7.1:游戏开发方面:
7.2:当线性表(包括数组)的元素个数较大,或者,根本不知道有多大时,最好用单链表
这样就不需要考虑存储空间的大小
7.3:采用顺序存储结构(比如数组):如果事先知道线性表(包括数组)的大致长度(比如一年12个月)
8:静态链表
8.1创建:
9:循环链表:circular linked list实现方法
p=rearA->next;
rearA->next=rearB->next->next;
q=rearB->next;
rearB->next=p;
free(q);/*释放B的头node*/
10:双向链表double linked list:用空间换时间
10.1:创建双向链表
typedef struct DulNode
{
ElemType data;
struct DulNode *prior;/*前驱指针*/
struct DulNode *next;
}DulNode,*DuLinkList;
10.2:双向链表图示
10.3插入操作:先搞定插入元素的前驱再后继,在搞定插入位置的前面的节点的的后继,再搞定插入位置后面的节点的前驱
s->prior=p;
s->next=p->next;
p->next->prior=s;/*让p->next的前驱变成s*/
p->next=s;
10.4删除操作:
p->prior->next=p->next;
p->next->prior=p->prior;