常见链表面试题的总结



/*
题目列表:


1. 求单链表中结点的个数
2. 将单链表反转
3. 查找单链表中的倒数第K个结点(k > 0)
4. 查找单链表的中间结点
5. 从尾到头打印单链表
6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序
7. 判断一个单链表中是否有环
8. 判断两个单链表是否相交
9. 求两个单链表相交的第一个节点
10. 已知一个单链表中存在环,求进入环中的第一个节点
11. 给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点
*/ 
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct node{                   
int data;
struct node *next;
}ElemSN;       //定义结点数据类型




/*
申请结点空间
*/
ElemSN * BuyNode(int value){          
ElemSN *p;
p = (ElemSN *)malloc(sizeof(ElemSN));
p->data = value;
p->next = NULL;
return p;
}  


/*
创建一个带表头结点的单链表
*/
ElemSN *CreatLink( int a[], int n){
ElemSN *h,*head;
ElemSN *p;
p = BuyNode(0);      //建立表头
if (p == NULL){
cout << "erro: malloc fail!!";
exit(1);
}
head = p;    
h = head;
for (int i = 0; i < n; i++){
p = BuyNode(a[i]);
if (p == NULL){
cout << "erro: malloc fail!!";
exit(1);
}
h->next = p;
h = p;
}
return head;
}


/*
创建单向循环链表
*/
ElemSN *CreatLoopLink(int a[], int n){
ElemSN *head, *p,*temp;
head = BuyNode(a[0]);
if (head == NULL){
cout << "erro: malloc fail!!";
exit(1);
}
temp = head;
temp->next = temp;
for (int i = 1; i < n; i++){
p = (ElemSN *)malloc(sizeof(ElemSN));
if (p == NULL){
cout << "erro: malloc fail!!";
exit(1);
}
p->data = a[i];
p->next = temp->next;
temp = temp->next = p;
}


return head;
}


/*
创建带环链表
*/
ElemSN *CreatCircleLink(int a[], int n, int m){
ElemSN *head, *p, *q;
head = CreatLoopLink(a, n);
p = q = head;
for (int i = 0; i < n-1; i++){
p = p->next;
}
if (m == 0){
return head;
}
else{
for (int i = 0; i < m-1; i++){
q = q->next;
}
}
p->next = q;
return head;
}


/*
创建相交链表
*/
void CrossLink(ElemSN * h1, ElemSN *h2, int m){
ElemSN *p, *q;
int i = 0;
for (p = h2; p->next; p = p->next);
for (q = h1; i < m; i++, q = q->next);
p->next = q;
}
/*
返回结点个数
*/
int getPointnum(ElemSN * head){
ElemSN * p;
int n = 0;
for (p = head; p; p = p->next){
n++;
}
return n;
}


/*
打印单链表
*/
void PrintLink(ElemSN * head){
ElemSN *p;
cout << "链表:" ;
for (p = head->next; p->next != NULL; p = p->next)
cout << p->data << " -> ";
cout << p->data << endl;
}
/*
打印带环链表
*/
void PrintCirelLink(ElemSN *head,int n){
ElemSN *p = head;
for (int i = 0; i < n;i++, p = p->next){
cout << p->data<<" ";
}
cout << endl;
}
/*
逆向打印单链表
*/
void PrePrintLink(ElemSN *head,ElemSN *flag){
if (head == NULL)  cout<<"逆向单链表:";
else{
PrePrintLink(head->next,flag);
if (head != flag) cout << head->data<<" -> ";
else              cout << head->data << endl;

}
}


/*
逆置链表
*/
ElemSN * PreLink(ElemSN *head){
ElemSN *p = head;
ElemSN *q = p->next;
if (head->next != NULL){
head = PreLink(head->next);
q->next = p;
p->next = NULL;
}
return head;
}


/*
寻找倒数第K个结点的位置
*/
ElemSN *Find_K_Point(ElemSN *head, int k){
ElemSN *p, *p1;
p = p1 = head;
for (int i = 0; i < k; i++)
p = p->next;


for (p; p; p = p->next, p1 = p1->next);


return p1;


}


/*
查找单链表的中间结点
*/
ElemSN *Find_middle_Point(ElemSN * head){
ElemSN *p,*p1;
for (p1 = p = head; p1&&p1->next; p = p->next, p1 = p1->next->next);
return p;


}


/*
O(1)删除指定结点
*/
void DeleteNode(ElemSN *head, int value){
ElemSN *p;
for (p = head; p->data != value; p = p->next);
p->data = p->next->data;
p->next = p->next->next;
}
/*
合并两个单链表(有序)
*/
ElemSN * MergeLink(ElemSN * head1, ElemSN *head2){
ElemSN *h, *t = NULL, *s;
h =BuyNode(0);
t = h;
while (head1&&head2)
{
if ((head1->data) <= (head2->data))    { s = head1;  head1 = head1->next; }
else                             { s = head2;  head2 = head2->next; }
s->next = NULL;
        t = t->next = s;
}
if (head1)   t->next = head1;
else     t->next = head2;
return h;
}
/*
判断是否带环
*/
int isCircleLink(ElemSN *head){
ElemSN *fast, *slow;
fast = slow = head;
while (fast&&fast ->next){
fast = fast->next->next;
slow = slow->next;
if (fast == slow) break;
}
return  !(fast == NULL || fast->next == NULL);
}
/*
判断链表是否相交
*/
int isCrossLink(ElemSN *h1, ElemSN *h2){
ElemSN *q, *p;
p = h1;
q = h2;
for (; p->next; p = p->next);
for (; q->next; q = q->next);
if (q == p)  return 1;
else         return 0;
}
/*
寻找相交链表的相交结点
*/
ElemSN * FindCrossNode(ElemSN *h1, ElemSN *h2){
ElemSN *q, *p,*t;
int i = 0;
p = h1;
q = h2;
for (; p!=q&&p&&q; p = p->next, q = q->next);
if (p == q) { 
if (p == NULL)  return NULL;
else            return p;
}
else
{

if (p){
t = p;
p = h1;
q = h2;
}
else {
t = q;
p = h2;
q = h1;
}
while (t){
t = t->next;
i++;
}
for (; i > 0; i--, p = p->next);
for (; q != p; p = p->next, q = q->next);
}
return p;
}
/*
寻找入环的第一个结点
*/
ElemSN * FindFirstNode(ElemSN *head){
ElemSN *fast, *slow,*p;
p = fast = slow = head;
while (fast&&fast->next){
fast = fast->next->next;
slow = slow->next;
if (fast == slow) break;
}
while (p != fast){
p = p->next;
fast = fast->next;
}
return p;
}
int main(void)
{
int n = 5, a[100], sumn, k, m, flag;
ElemSN * head = NULL,*head1,*head2,*head3,*q,*middle,*headcricle,*h,*h2,*tag;

cout << "请输入数据个数与环开始结点数:";
cin >> n >> m;
cout << "\n请输入结点的值:";
for (int i = 0; i < n; i++)
cin >> a[i];
cout << "\n输入要查询的倒数第k个结点的值:";
cin >> k;
    /*
相交的链表操作
*/
h2 = CreatLink(a, 3);            
PrintLink(h2);
h = CreatLink(a, n);       
CrossLink(h, h2, 3);    //创建相交链表
cout << "相交链表1:";
PrintLink(h);
cout << "相交链表2:";
PrintLink(h2);
cout << "是否相交:";
cout << isCrossLink(h, h2) << endl;
tag = FindCrossNode(h->next, h2->next);
cout << "相交结点值:";
cout << tag->data<<endl;




/*
带表头的单链表操作
*/


head = CreatLink( a, n);      //创建带表头的结点head
head1 = CreatLink(a, n);    //创建带表头的结点head1
head2 = CreatLink(a, n);    //创建带表头的链表head2
cout << "原";
PrintLink(head);                 //输出链表
PrePrintLink(head->next, head->next);//逆向输出链表
head->next = PreLink(head->next);//逆置链表 
cout << "逆置后的";
PrintLink(head);                 //输出链表
q = Find_K_Point(head, k);       //寻找倒数第K个结点的位置
sumn = getPointnum(head->next);        //得到结点的个数 
middle = Find_middle_Point(head->next);//得到中间结点的位置
cout << "倒数第" << k << "个结点的值:" << q->data << endl;       //输出第k个结点的值
cout << "中间结点:" << middle->data << endl;
cout << "结点个数:" << sumn << endl;
head = MergeLink(head1->next, head2->next); //合并链表head1,head2(有序)
cout << "合并后的";
PrintLink(head);                           //输出合并后的链表 */
PrintLink(head2);
DeleteNode(head2, 3);
cout << "O(1)删除指定结点:"<<endl;
PrintLink(head2);




/*
带环链表操作
*/
head3 = CreatCircleLink(a, n, m);//创建带环链表head3
headcricle = FindFirstNode(head3);
PrintCirelLink(head3,20);
flag =  isCircleLink(head3);
if (flag) {
cout << "有环,开始结点为:" << headcricle->data << endl;
}
else      cout << "无环"<<endl;
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值