链表总结

链表是面试笔试中考的频率最高的,因此可以用最短的代码量考查最多的知识。

一个链表的结构首先包含数据和下一个节点的位置,通过结构体来声明:

struct  listNode

{

 int value;

 listNode* next;//指向下一个节点,通过这个指针所指向的位置可以查找到下一个节点的位置

}

首先最基本的呢,就是在链表尾部进行插入一个新的节点,这些在数据结构中都可以找到,插入、删除节点是作为最基本的链表的操作,其次是查找是否存在某一节点。

void   insert(listNode**  head,int value)

{

listNode*  newnode = new  listNode();//分配一个空间

newnode->value=value;

newnode->next=NULL;

if(*head==NULL)

 *head=newnode;

else

{

listNode* pNode=*head;

while(pNode->next!=NULL)

pNode=pNode->next;

pNode->next=newnode;

}

}

//切记的一点就是head指针式指向指针的指针,当我们往一个空链表插入一个结点时,新插入的节点就是链表的头节点。由于此时会改动头节点,因此我们必须把head参数设为指向指针的指针。否则出了这个函数head仍然是一个空指针。

#include <iostream>
using namespace std;
struct LinkList
{
    int lValue;
    LinkList* next;
};

int IsLoop(LinkList *head)
{
    LinkList *pSlow=head;
    LinkList *pFast=head;
    while(pSlow!=NULL && pFast!=NULL)
    {
        pSlow=pSlow->next;
        pFast=pFast->next->next;
        if(pSlow==pFast)
            return 2;
    }
    return 3;
}
int ListLength(LinkList* &L)
{
    int i=0;
    LinkList* p=L->next; /* p指向第一个结点 */
    while(p)
     {
        i++;
        p=p->next;
     }
        return i;
}
int main(void)
{
    LinkList* head=new LinkList;
    LinkList* l1=new LinkList;
    LinkList* l2=new LinkList;
    LinkList* l3=new LinkList;
    LinkList* l4=new LinkList;
    //l1=head;
    //head->next=NULL;
    
    l1=    head;
    l1->lValue=22;
    l1->next=l2;
    l2->lValue=23;
    l2->next=l3;
    l3->lValue=24;
    l3->next=l4;
    l4->lValue=25;
    l4->next=NULL;
    int isCircle=IsLoop(head);
    int lenght=ListLength(head);
    cout<<lenght<<endl;
    cout<<isCircle<<endl;
}

上面是求单链表是否存在环,以及单链表的长度!中间有些被我改了做测试!其实通过写一个函数来实现插入解耦是最好的,这样可以判断new出来在堆空间的分配是否存在内存。

//#include <iostream>
//using namespace std;
//struct LinkList
//{
//    int lValue;
//    LinkList* next;
//};
void Isloop(Llink head)
{
    if(!head||!head->next)
        return;
    Llink p,q;
    bool loop=false;
    p=q=head->next;
    while(q&&q->next)//判断是否有环
    {
        p=p->next;
        q=q->next->next;
        if(p==q)
        {
            loop=true;
            break;
        }
    }
    if(!loop)
        cout<<"This link has not loop\n";
    else
    {
        cout<<"This link has a loop\n";
        Llink r=p;
        q=head->next;
        int nonloop=1,loopcount=1;

        //nonloop计算非环结点数,loopcount计算环上结点数
        do//计算环上的结点数
        {
            p=p->next;
            ++loopcount;
        }while(p!=r);
        --loopcount;
        while(p!=q)//得到环的入口结点,同时计算得到非环的结点数
        {
            p=p->next;
            q=q->next;
            ++nonloop;
        }
        --nonloop;
        cout<<"\nStart of loop: "<<p->data<<endl;  
        cout<<"\nCount of nonloop: "<<nonloop
            <<"\nCount of loop: "<<loopcount
            <<"\nCount of Linknode: "<<nonloop+loopcount<<endl;
    }
}
//int IsLoop(LinkList *head)
//{
//    LinkList *pSlow=head;
//    LinkList *pFast=head;
//    while(pSlow!=NULL && pFast!=NULL)
//    {
//        pSlow=pSlow->next;
//        pFast=pFast->next->next;
//        if(pSlow==pFast)
//            return 2;
//    }
//    return 3;
//}
//int ListLength(LinkList* &L)
//{
//    int i=0;
//    LinkList* p=L->next; /* p指向第一个结点 */
//    while(p)
//     {
//        i++;
//        p=p->next;
//     }
//        return i;
//}
//int main(void)
//{
//    LinkList* head=new LinkList;
//    LinkList* l1=new LinkList;
//    LinkList* l2=new LinkList;
//    LinkList* l3=new LinkList;
//    LinkList* l4=new LinkList;
//    //l1=head;
//    //head->next=NULL;
//    
//    l1=    head;
//    l1->lValue=22;
//    l1->next=l2;
//    l2->lValue=23;
//    l2->next=l3;
//    l3->lValue=24;
//    l3->next=l4;
//    l4->lValue=25;
//    l4->next=NULL;
//    int isCircle=IsLoop(head);
//    int lenght=ListLength(head);
//    cout<<lenght<<endl;
//    cout<<isCircle<<endl;
//}
#include "stdio.h"
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
    
#define MAXSIZE 20 /* 存储空间初始分配量 */

typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */
    
typedef struct Node
{
    ElemType data;
    struct Node *next;
}Node;
/* 定义LinkList */
typedef struct Node *LinkList;
        
/* 初始化顺序线性表 */
Status InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
    if(!(*L)) /* 存储分配失败 */
    {
    return ERROR;
    }
    (*L)->next=NULL; /* 指针域为空 */
            
    return OK;
    }
        
/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
int ListLength(LinkList L)
{
    int i=0;
    LinkList p=L->next; /* p指向第一个结点 */
    while(p)
     {
        i++;
        p=p->next;
     }
        return i;
}
        
int main()
{
    LinkList L;
    Status i;
            
    i=InitList(&L);
    printf("链表L初始化完毕,%d\n",i);
    printf("链表L初始化完毕,ListLength(L)=%d\n",ListLength(L));
}
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
    int data;
    struct Node *next;
}List;
void Init(List* &L)
{
    L=(List *)malloc(sizeof(List *));
    L->next=NULL;
}
void Create(List *&L,int a[],int n)
{
    List *p,*q;
    int i;
    q=L;
    for(i=0;i<n;i++)
    {
        p=(List *)malloc(sizeof(List *));
        p->data=a[i];
        p->next=q->next;
        q->next=p;
        q=p;
    }
}
int main()
{
    List  L;
                
    Init(&L);
    printf("链表L初始化完毕,ListLength(L)=%d\n",ListLength(L));
}
#include "stdio.h"
002    
003    #define OK 1
004    #define ERROR 0
005    #define TRUE 1
006    #define FALSE 0
007    
008    #define MAXSIZE 20 /* 存储空间初始分配量 */
009    
010    typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
011    typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */
012    
013    typedef struct Node
014    {
    015        ElemType data;
    016        struct Node *next;
    017    }Node;
    018    /* 定义LinkList */
        019    typedef struct Node *LinkList;
    020    
        021    /* 初始化顺序线性表 */
        022    Status InitList(LinkList *L)
        023    {
            024        *L=(LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
            025        if(!(*L)) /* 存储分配失败 */
                026        {
                    027            return ERROR;
                    028        }
            029        (*L)->next=NULL; /* 指针域为空 */
            030    
                031        return OK;
            032    }
    033    
        034    /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
        035    int ListLength(LinkList L)
        036    {
            037        int i=0;
            038        LinkList p=L->next; /* p指向第一个结点 */
            039        while(p)
                040        {
                    041            i++;
                    042            p=p->next;
                    043        }
            044        return i;
            045    }
    046    
        047    /* 初始条件:顺序线性表L已存在 */
        048    /* 操作结果:依次对L的每个数据元素输出 */
        049    Status ListTraverse(LinkList L)
        050    {
            051        LinkList p=L->next;
            052        while(p)
                053        {
                    054            visit(p->data);
                    055            p=p->next;
                    056        }
            057        printf("\n");
            058        return OK;
            059    }
    060    
        061    Status visit(ElemType c)
        062    {
            063        printf("-> %d ",c);
            064        return OK;
            065    }
    066    
        067    /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
        068    /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
        069    Status ListInsert(LinkList *L,int i,ElemType e)
        070    {
            071        int j;
            072        LinkList p,s;
            073        p = *L;     /* 声明一个结点 p,指向头结点 */
            074        j = 1;
            075        while (p && j < i)     /* 寻找第i个结点 */
                076        {
                    077            p = p->next;
                    078            ++j;
                    079        }
            080        if (!p || j > i)
                081            return ERROR;   /* 第i个元素不存在 */
            082        s = (LinkList)malloc(sizeof(Node));  /*  生成新结点(C语言标准函数) */
            083        s->data = e;
            084        s->next = p->next;      /* 将p的后继结点赋值给s的后继  */
            085        p->next = s;          /* 将s赋值给p的后继 */
            086        return OK;
            087    }
    088    
        089    int main()
        090    {
            091        LinkList L;
            092        Status i;
            093        int j,k;
            094        char opp;
            095    
                096        i=InitList(&L);
            097        printf("链表L初始化完毕,ListLength(L)=%d\n",ListLength(L));
            098    
                099        printf("\n1.遍历操作 \n2.插入操作  \n0.退出 \n请选择你的操作:\n");
            100        while(opp != '0'){
                101            scanf("%c",&opp);
                102            switch(opp){
                    103                case '1':
                    104                    ListTraverse(L);
                    105                    printf("\n");
                    106                    break;
                    107    
                        108                case '2':
                    109                    srand((unsigned)time(NULL));
                    110                    for(j=1;j<=10;j++)
                        111                    {
                            112                        i=ListInsert(&L,1,rand()%100);
                            113                    }
                    114                    printf("在L的表头依次插入10个随机数后:");
                    115                    ListTraverse(L);
                    116                    printf("\n");
                    117                    break;
                    118    
                        119           case '0':
                                   exit(0);
                                }
                        }
                
                }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值