还是一个新手小白,初次尝试写博客,希望大家多多指教,这是最近学的有关链表的一些知识。
1. 链表的结构类型
typedef struct linklist
{
int data;
struct linklist *next;
}linklist;
2.链表的输入
linklist *Creatlist(linklist *head,int *indata,int num)
{
int i=0;
linklist *current=(linklist*)malloc(sizeof(linklist));
current=head;
for(i=0;i<num;i++)
{
current->data=indata[i];
if(i<num-1)
{
current->next=(linklist*)malloc(sizeof(linklist));
current=current->next;
}
else current->next = NULL;
//if语句可以保证没有多余的链表创建,并且最后一个链表的下一个链表为空。
}
return head;
}
3.链表的反转
这个是新学的,了解了两个方法。
法一:迭代法
linklist *ReverseList(linklist *head)
{
node* prev,*ne,*tmp;
prev=head; //防止头结点丢失
ne = tmp = head->next ;
prev->next = NULL;
while(ne!=NULL)
{
ne = ne->next ; //用来保存下一个结点
tmp->next = prev; //使这个结点指向反转完的链表
prev = tmp; //链表的尾结点变为当前结点
tmp = ne;
}
return prev;
}
法二:递归
node* reverseList(node* head)
{
if (head == NULL || head->next == NULL)
return head;
node* reverse = reverseList(head->next);
//此时reverse永远存储的是尾结点,即新链表的头结点。
head->next->next = head; //当前结点的下下个结点指向自己,则完成了链表的反转
head->next = NULL;
return reverse;
}
首先,递归的结束条件应该放在最前面,如果在循环的后面就会永不结束。
其次,第二,三条语句的意思是:reverse是反转之后的链表的头结点,反转完之后head是链表reverse的尾结点。注意!尾结点都为空,不然会成环。
4.合并有序链表
这个题其实也有递归,迭代两种方法,但在我看来迭代相较递归更容易一些。
法一:迭代
linklist *reservelist(linklist *l1,linklist *l2)
{
linklist *head,*prev=head;
while(l1!=NULL&&l2!=NULL)
{
if(l1->data < l2->data)
{
prev->next=l1;
l1=l1->next;
}
else
{
prev->next=l2;
l2=l2->next;
}
prev=prev->next; //不管l1,l2谁移动prev总要进入下一个结点
}
return head;
}
法二:递归
linklist *reservelist(linklist *l1,linklist *l2)
{
if(l1==NULL) return l2;
else if(l2==NULL) return l1;
//谁先结束说明这个链表已经按序插入另一个链表里了,剩下的结点已是升序排好,直接接入前面排好的链表即可
else if(l1->data < l2->data)
{
l1->next=ListNode(l1->next,l2);
return l1; //!!!!!别忘了返回这一步递归的值
}
else if(l1->data > l2->data)
{
l2->next=ListNode(l1,l2->next);
return l2;
}
}
5.两两交换链表的值
这个题可以两两分组进行交换,两个交换完之后再交换下一组。
法一:递归法
返回值:交换完成的子链表
调用单元:设需要交换的两个点为 head 和 next,head 连接后面交换完成的子链表,next 连接 head,完成交换
终止条件:head 为空指针或者 next 为空指针,也就是当前无节点或者只有一个节点,无法进行交换
linklist * ExchangeNode(linklist *head)
{
if(head == NULL || head->next == NULL)
return head;
linklist *next=head->next ;
head->next = ExchangeNode(next->next);
//第一个结点应接交换完的链表的首结点
next->next = head;
return next;
}
法二:迭代
linklist *ExchangeNode(linklist *head)
{
linklist prehead,*tmp;
prehead.next = head; //用于储存头结点,防止头结点丢失
tmp=&prehead;
while(tmp!=NULL||tmp->next!=NULL)
{
node *n1,*n2;
n1=tmp->next;
n2=tmp->next->next;
tmp->next = n2;
n1->next = n2->next ; //先对n1进行改变再改变n2
n2->next = n1;
tmp=n1;
}
return prehead.next;
}
以上是我最近学的认为值得分享的方法及思维,还有一些注意的点,如果有什么好的题或思路,大家也可以一起分享啊![ღ( ´・ᴗ・` )比心]
最后,谢谢大家的观看,如果有更好的方法可以评论区留言哦。