为了能够促进学习成效,特记录自己学习中遇到的一些问题。
链表早在很久之前就学习过了,并没有很难,不过在做题的时候我发现了一些问题,这个问题我在稍后会提到。
首先呢,链表的种类分为两种,一种是静态链表,一种是动态链表。
静态链表是借助于数组来实现链表的功能,具有随机访问的特点,当然缺点是浪费空间。
动态链表则是通过指针的方式,将一个一个的结点进行连接,优点是节省空间,缺点是只能顺序访问。
从静态链表和动态链表的优缺点可以看出,两者间并没有绝对的好与坏之分,具体问题具体使用。
静态链表没有什么可以讲得,所以就讲一讲动态链表。
动态链表又分为单向链表,双向循环链表。
单向链表则只能访问该节点的下一个节点,而无法访问上一个节点,而双向循环链表则解决了这一问题,但是也占用了额外的空间存放上一个节点的地址,所以也是具体问题具体使用。
首先给出单链表的结构体定义:
typedef struct list_node{
elemtype data ;
struct list_node *next ;
}List_Node , List ;
有了单链表的定义之后就好办多了,然后开始创建单链表:
void Build_List(List L , int n){
List q , p ;
q = L ;
for(int i = 1 ; i <= n ; ++i){
p = (List)malloc(sizeof(List_Node)) ;
cin >> p->data ;
q->next = p ;
q = p ;
}
q->next = NULL ;
}
上面就是创建单链表的过程,该函数总共有两个参数,一个是头结点L,一个是创建的节点数n。
创建完成后,则就可以进行输出了,以下为输出代码:
void Print_List(List L)
{
List q , p ;
q = L->next ;
while(q){
p = q->next ;
free(q);
q = p ;
}
free(L);
}
在这里使用free是因为malloc分配的空间如果不释放则只能到程序结束时才会释放,而malloc的内存块属于堆内,则可能会造成堆溢出的问题,所以最后在使用完后释放结点。
当然,动态链表相较于数组的一大优点是插入删除方便,由于插入的方式与创建链表的方式类似,所以就参考链表的建立吧。接下来介绍一下删除操作:
void Delete_Operator(List L , elemtype data){
List q , p ;
q = L->next ;
p = L ;
while(q->data != data && q){
p = q ;
q = q->next ;
}
if(q)
p->next = q->next ;
}
首先说明一点,这里删除元素的时候并没有判空,因为在while语句内加了一句若q为空,则说明要么是头结点该链表中没有要删除的元素data,所以不执行。
取元素类似删除操作,不同支持是并没有删除节点,原来的节点还是在链表上,而不是向删除元素那样,将节点从链表中删除,若是有不明白的地方可以评论说一下。