实习整理(十四)
来源:互联网 发布:美国华人医师网络医院 编辑:程序博客网 时间:2024/06/04 18:19
前面一篇博文简要地讲了下我在笔试准备过程中碰到过的有关字符串的题目,现在再提下有关链表的题目
(1) 具有链表头的单链表
{
}
typedef struct student
{
int number;
char name[20];
int score;
struct student *next;
}student;
student *reverse2(student *stu)
{
student *p1,*p2,*p3;
if(stu == NULL ||stu->next == NULL)
return stu;
p1=stu; //p1指向链表的第一个节点
p2=p1->next;
while(p2)
p3=p2->next;
p2->next = p1;
p1=p2;
p2=p3; }
printf("p1 = %d,next = %d\n ",p1->number,p1->next->number);
stu=p1; //将链表第一个节点指向p1
return stu;
}
{
if(p == NULL || p->next == NULL)
{
head = p;
return p;
}
else
{
List* q = reverse(p->next, head);
q->next = p;
return p;
}
node* tail= head->next;
head->next=NULL;
return newHead;
}
比如有下面两个链表:
链表2:2->4->6
递归方法的步骤如下:
(1)比较链表1和链表2的第一个节点数据,由于1<2,因此把结果链表头节点指向链表1中的第一个节点,即数据1所在的节点。
(2)对剩余的链表1(3->5)和链表2再调用本过程,比较得到结果链表的第二个节点,即2与3比较得到2。此时合并后的链表节点为1->2。
接下来的过程类似(2),如此递归直到两个链表的节点都被加到结果链表中
node * MergeRecursive(node *head1, node *head2)
{
node *head = NULL;
if (head1 == NULL)
{
return head2;
}
if (head2 == NULL)
{
return head1;
}
if ( head1->data < head2->data )
{
head = head1 ;
head->next = MergeRecursive(head1->next,head2);
}
else
{
head = head2 ;
head->next = MergeRecursive(head1,head2->next);
{
Node *res, *ret, *p, *q;
if(head1 == NULL) return head2;
ret = res = head1;
q = head2->next;
while(p && q)
{
if(p->value < q->value)
{
res->next = p;
res = p;
p = p->next;
}
else
{
res->next = q;
res = q;
q = q->next;
}
}
res->next = p ? p : q; //p或q有剩,把剩下的链表插入到结果链表后
return ret;
}
dnode *deletenode(dnode *head,dnode *node)
{
if(node->pre == NULL)
{
// 头结点
head = head->next;
head->pre = NULL;
}
else if(node->next == NULL)
{
// 尾结点
node->pre->next = NULL;
}
else
{
// 中间结点
node->pre->next = node->next;
node->next->pre = node->pre;
}
free(node);
return head;
}
node *findMid(node *head) // 有链表头
{
if(NULL == head)
return NULL;
node *fast, *slow;
fast = slow = head;
while((fast != NULL) && (fast->next != NULL))
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
node *findMid(node *head) // 无链表头
{
if(NULL == head)
return NULL;
if(head->next == NULL || head->next->next == NULL)
return head;
node *fast = head;
node *slow = head;
while(fast->next != NULL && fast->next->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
设置两个指针(fast, slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定 相遇。(当然,fast先行头到尾部为NULL,则为无环链表)
当fast若与slow相遇时,slow肯定没有走遍历完链表,而fast已经在环内循环了n圈(1<=n)。假设slow走了s步,则 fast走了2s步(fast步数还等于s 加上在环上多转的n圈),设环长为r,则:
2s = s + nr
s= nr
设整个链表长L,入口环与相遇点距离为x,起点到环入口点的距离为a。
a + x = nr
a + x = (n – 1)r +r = (n-1)r + L - a
a = (n-1)r + (L – a – x)
{
if(NULL == head)
return NULL;
node *fast, *slow;
fast = slow = head;
while((fast != NULL) && (fast->next != NULL))
{
fast = fast->next->next; //走两步
slow = slow->next; //走一步
if(fast == slow){ //有环
fast = head;
while(fast != slow){
fast = fast->next;
slow = slow->next;
}
return fast;
}
}
return NULL;
}
未完待续。。。
- 实习整理(十四)
- 安卓实习期间整理知识点(十四)
- 实习小结十四:无题
- 读书笔记整理十四:
- 实习整理(一)
- 实习整理(二)
- 实习整理(三)
- 实习整理(四)
- 实习整理(五)
- 实习整理(六)
- 实习整理(七)
- 实习整理(八)
- 实习整理(九)
- 实习整理(十)
- 实习整理(十一)
- 实习整理(十二)
- 实习整理(十三)
- 实习整理(十五)
- XML 文件读写 自己
- quartz
- Gson使用
- camera中设置界面初探
- linux下bluetooth编程(一)基础概念
- 实习整理(十四)
- zTree动态添加节点
- 字符串和编码
- PHP Redis类操作
- Windows环境下生成Apple证书教程
- ExecutorService线程池讲解
- [Mysql数据库] mysql数据库的连接以及增删改查Java代码实现
- 系统权限
- 【网络】远程通信(RPC,Webservice,RMI,JMS、EJB、JNDI的区别)对比