线性表之链表

1.初始化

void InitList(List plist)

{

assert(plist!=NULL);

if(plist==NULL)

{

return;

}

//plist->data;//不使用

plist->next=NULL;

}

2.头插

bool Insert_head(List plist,int val)//时间复杂度为O(1)

{

Node *p = (Node *)malloc(sizeof(Node));

p->data = val;

p->next = plist->next;

plist->next = p;//p就指向malloc分配空间的地址(即sizeof里的东西)

/*

Node newnode;//1

newnode.data = val;//2

newnode.next = plist->next;//4  防止气球飞走( 防止内存泄漏)

plist->next = &newnode;//3

*/

return true;

}

3.尾插

bool Insert_tail(List plist,int val)//O(n)

{

Node *p = (Node *)malloc(sizeof(Node));

p->data = val;

Node *q;

for(q = plist;q->next!=NULL;q = q->next);//找尾巴

//将p插入在q之后

p->next = q->next;//p->next = NULL;

q->next = p;

return true;

}

4.查找

Node *Srearch(List plist,int key)

{

for(Node *p = plist->next;p!=NULL;p = p->next)

{

if(p->data == key)

   {

return p;

   }

}

return NULL;

}

5.删除    删除依赖于前驱

bool Delete(List plist,int key)

{

Node *p;//p是q的前驱

for(p = plist;p->next!=NULL;p = p->next)

{

if(p->next->data == key)

        {

Node *q = p->next;//记录要删除的节点

p->next = q->next;

free(q);

return true;

}

}

return false;

}

6.获取数据节点个数(不包含头节点)

int GetLength(List plist)

{

int count = 0;

for(Node *p = plist->next;p!=NULL;p = p->next)//遍历所有数据节点

{

count++;

}

return count;

}

7.判断链表是否为空(不包含头节点)

bool IsEmpty(List plist)

{

return plist->next == NULL;

}

8.清除数据

void Clear(List plist)

{

Destroy(plist);

}

9.摧毁数据

(1)最简单的方法

void Destroy(List plist)

{

Node *p;

while(plist->next!=NULL)

//为什么用plist->next而不用plist?

//这个摧毁数据的方法是最简单的,只摧毁最前面的第一个数据,后面的挨个向前走,正如排队买饭,阿姨不动,而同学们打一份,走一个人

{

p = plist->next;

plist->next = p->next;

free(p);

}

}

(2)逐个摧毁

void Destroy(List plist)

{

Node *p = plist->next;

Node *q;

while(p!=NULL)

{

q = p->next;//q是p的后继

free(p);

p = q;

}

plist->next = NULL;

}

10.打印

void Show(List plist)

{

for(Node *p = plist->next;p!=NULL;p = p->next)

{

printf("%d ",p->data);

}

printf("\n");

}

11.得到某一位置的元素

//第一数据节点的pos为0

bool GetElen(List plist,int pos,int *rtval)

{

if(pos<0 || pos>Getlength(plist))

{

return false;

}

int i = 0;

for(Node *p = plist->next;p!=NULL;p = p->next)

{

if(i == pos)

{

*rtval = p->data;

return true;

}

i++;

}

return false;

}

12.得到结点p的前驱

static Node *GetPri(List plist,Node *p)

{

for(Node *q = plist;q->next!=NULL;q = q->next)

{

if(q->next == p)

{

return q;

}

}

return NULL;

}

13.逆置

void Reverse(List plist)//考试的重点内容

{

if(plist == NULL || plist->next == NULL || plist->next->next == NULL)//分别是:这个链表不存在;只有一个头结点;只有一个数据元素

{

return;

}

//下面的时间复杂度为O(n),并且最好,利用头插的思想

Node *p = plist->next;

Node *q;

plist->next = NULL;//保证最后一个结点的next项为NULL

while(p!=NULL)

{

q = p->next;//q是p的后继,q要插到p后面

p->next = plist->next;//将结点p头插到链表中

plist->next = p;


p = q;//往下走

}

//因为q保存了后面的结点,所以将p与后面的结点断开没有关系,再与前面的plist相连

/*

//下面的时间复杂度为O(n)    向后转

Node *p = plist->next;

Node *q = p->next;

Node *s;

p->next = NULL;//保证最后一个结点的next项为NULL


while(q != NULL)//注意区分q和q->next的区别

{

s = q->next;

q->next = p;//反转

p = q;

q = s;

}

plist->next = p;将反转后的第一个结点与头结点相连

*/


/*

//下面方法的时间复杂度为O(n^2)

Node *p = plist->next;

Node *q;

int tmp;


for(Node *q = plist;q!=NULL;q = q->next);//注意这不是for循环嵌套


for(int i = 0;i<GetLength(plist)/2;i++)

{

tmp = p->data;

p->data = q->data;

q->data = tmp;


p = p->next;

q = GetPri(plist,q);

}

*/

}

14.链表里不再有重复的元素

void Unique(List plist)

{

Node *p;

Node *q;

for(p = plist->next;p!=NULL;p = p->next)

{

for(q = p;q->next!=NULL;q = q->next)

{

if(q->next->data == p->data)

{

Node *s = q->next;

q->next = s->next;

free(s);

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@所谓伊人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值