下面是自己的一些学习操作以及总结,能用我会很开心,有不足之处,欢迎大家提出宝贵的意见!
c语言链表是一种基本的数据结构,与顺序表一样属于线性表,但是顺序表在内存中的存储单元是连续的,这样就对内存的要求比较高,而链表就不一样了,它能够很好的解决这些缺点,唯一不足就是访问元素的效率不如顺序表来的那么高,但也只是相对而言!而且,链表对于后面的二叉树,图等意义重大,他们之间的联系都是非常紧密的,下面我来给出链表的一些操作。
1、链表的存储结构由数据和指针组成一个节点,每一个指针指向下一个节点,这样环环相扣就形成了链表
typedef int T;
//链表节点
typedef struct Node
{
T data;
struct Node* next;
}Node,*Link;
这段是链表的节点定义。
2、
//创建一个链表,返回的是头指针。
Link createlink()
{
Node* link=(Node*)malloc(sizeof(Node));
link->next=NULL;
return link;
}
3、
//判断链表是否为空
bool isempty(Link link)
{
return link->next==NULL;
}
4、
//获得链表元素的个数
size_t size(Link link)
{
size_t num=0;
Link p=link->next;
while(p!=NULL)
{
num++;
p=p->next;
}
return num;
}
5、
//获得index前一个节点,这里的这个函数获得的节点是指定位置前一个节点
Node* getnode(Link link,int index)
{
Link p=link;
for(int i=1;i<=index;i++)
{
p=p->next;
}
return p;
}
6、
//插入元素到指定位置 index从0开始到size()
bool insert(Link link,int index,T value)
{
if(index>size(link)||index<0)
{
return false;
}
Link s=(Node*)malloc(sizeof(Node)),q;
q=getnode(link,index);//调用上面的函数获取节点。
s->data=value;
s->next=q->next;
q->next=s;
return true;
}
7、//下面分别是在链表头插或者是尾部插入元素,也可以使用上面的另index为0或者为链表长度即可!
bool insertback(Link link,T value)
{
Link s=(Node*)malloc(sizeof(Node));
s->data=value;
s->next=link->next;
link->next=s;
}
bool insertfront(Link link,T value)
{
Link s=(Node*)malloc(sizeof(Node));
Link r=link;
while(r->next!=NULL)
{
r=r->next;
}
s->data=value;
r->next=s;
r=s;
r->next=NULL;
}
8、
//更新链表下标为index的节点值
bool update(Link link,int index,T value)
{
if(index>size(link)-1||index<0)
{
return false;
}
Link s=getnode(link,index);
Node* q=s->next;
q->data=value;
free(q);
return true;
}
9、
//删除指定下标的元素
bool deletelink(Link link,int index)
{
if(index>size(link)-1||index<0)
{
return false;
}
Node* s=getnode(link,index);
Node* q=s->next;
s->next=q->next;
free(q);
}
10、
//删除value的所有节点
bool deletedatas(Link link,T value)
{
Node* node=link->next;
Node* prenode=link;
bool flag=false;
while(node!=NULL)
{
if(node->data==value)
{
prenode->next=node->next;
Node* tmp=node;
node=node->next;
free(tmp);
flag=true;
continue;
}
prenode=node;
node=node->next;
}
return true;
}
11、
//删除value的第一次元素
bool deletedata(Link link,T value)
{
/*int index=indexof(link,value);
if(-1==index)
{
return false;
}
Link s=getnode(link,index);
Node* q=s->next;
s->next=q->next;
free(q);
return true;*/
Node* node=link->next;
Node* prenode=link;
while(node!=NULL)
{
if(node->data==value)
{
prenode->next=node->next;
free(node);
return true;
}
prenode=node;
node=node->next;
}
return false;
}
//查找是否存在value元素
bool isexists(Link link,T value)
{
// if(isempty(link))return false;
Node* node=link->next;
while(node!=NULL)
{
if(node->data==value)
{
return true;
}
node=node->next;
}
return false;
}
int indexof(Link link,T value)
{
Node* node=link->next;
int index=0;
while(node!=NULL)
{
if(node->data==value)
{
return index;
}
index++;
node=node->next;
}
return -1;
}
12、
//遍历输出
void travel(Link link)
{
Node* node=link->next;
while(node!=NULL)
{
printf("%d ",node->data);
node=node->next;
}
printf("\n");
}
13、
//逆序
void reverse(Link link)
{
//Node* pprevnode=link;
if(link==NULL||link->next==NULL)
{
return;
}
//记录前一个节点
Node* prevnode=link->next;
//记录当前节点
Node* node=prevnode->next;
//只要当前节点存在
while(node!=NULL)
{//先记录当前节点的后一节点
Node* nextnode=node->next;
//让当前节点的下一个节点指向前一个节点
node->next=prevnode;
prevnode=node;
node=nextnode;
}
//让原来的第一个元素变为尾元素,尾元素的下一个置空
link->next->next=NULL;
//让链表的头节点指向原来的尾巴元素
link->next=prevnode;
}
14、
//清空链表
void clear(Link link)
{
Node* node=link->next;
while(node!=NULL)
{
Node* tmp=node;
node=node->next;
free(tmp);
}
link->next=NULL;
}
//销毁
void destroy(Link link)
{
clear(link);
free(link);
link=NULL;
}
15、需要加入的头文件
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
最后,有什么问题欢迎大家提问和提出意见,也欢迎大家补充!