数据结构(1)-链表

数据结构在编程中或多或少都会用到,也是程序员面试最喜欢问的知识块之一,可以说非常基础了。本篇文章主要介绍链表,但不从理论部分介绍,直接给出链表的实现代码。当然,本人还是建议先看一遍链表理论部分的知识再来看本文的程序,这样掌握的更快更牢。相关的理论知识可以查看相关书籍或直接百度。下面直接上代码。

/*-----------------------------程序描述--------------------------------------------
* 本程序展示链表的创建、输出、删除、插入和查找等操作。主函数中分别调用
* (1) 建立链表的函数Creat(),
* (2) 输出链表的函数Print(),
* (3) 查找结点的函数Find(),
* (4) 插入结点的函数Insert(),
* (5) 逆转结点的函数Reversed(),
* (6) 删除链表结点的函数Delete(),
* (7) 清屏
* (8) 退出
* (9) 每K个结点逆转的函数KReversed(),
* 一共9个函数。

* Author:EthanYYYY
* Date:  2017.12.20
----------------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

typedef struct node{
    int _val;
    struct node* next;
}Node;

int _iNodeCout;

Node* Creat();
Node* Delete(Node*,int);
void Find(Node* ,int);
Node* Insert(Node*,Node*);
void Print(Node*);
Node* Reversed(Node*);
Node* KReversed(Node*,int);

int main(int argc, char *argv[])
{
    volatile int _iChoice;
    int _iNode;
    Node* pHead=NULL;
    Node* insertNode=NULL;
    int k;
    do
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
        printf("\n\t ------------------------------------------------------");
        printf("\n\t|         [1] creat             [2] print              |");
        printf("\n\t|         [3] search            [4] insert             |");
        printf("\n\t|         [5] reversed          [6] delete             |");
        printf("\n\t|         [7] clear             [8] exit               |");
        printf("\n\t|         [9] K-reversed        [10]                   |");
        printf("\n\t ------------------------------------------------------\n");
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7|0);

        printf("you choice: ");
        scanf("%d",&_iChoice);

        switch (_iChoice)
        {
        case 1:
            pHead=Creat();
            break;
        case 2:
            Print(pHead);
            break;
        case 3:
        {
            printf("input search node:");
            scanf("%d",&_iNode);
            Find(pHead,_iNode);
        }
            break;
        case 4:
        {
            printf("input insert node:");
            insertNode=(Node*)malloc(sizeof(Node));
            scanf("%d",&insertNode->_val);
            insertNode->next=NULL;
            pHead=Insert(pHead,insertNode);
        }
            break;
        case 5:
            pHead=Reversed(pHead);
            break;
        case 6:
        {
            printf("input delete node:");
            scanf("%d",&_iNode);
            pHead=Delete(pHead,_iNode);
        }
            break;
        case 7:
            system("CLS");
            break;
        case 8:
            _iChoice=-1;
            break;
        case 9:
        {
                printf("input K = ");
                scanf("%d",&k);
                pHead=KReversed(pHead,k);
        }
            break;
        default:
            puts("invaild,choose again!");
            break;
        }
    } while (_iChoice!=-1);

    system("pause");
    return 0;
}

Node* Creat()
{
    Node* pHead=NULL,* pCur,* pTail;
    _iNodeCout=0;
    puts("input node, end whit -1:");
    pCur=pTail=(Node*)malloc(sizeof(Node));
    scanf("%d",&pCur->_val);
    pCur->next=NULL;
    while (pCur->_val!=-1)
    {
        _iNodeCout++;
        if(1==_iNodeCout) pHead=pCur;
        else pTail->next=pCur;
        pTail=pCur;
        pCur=(Node*)malloc(sizeof(Node));
        scanf("%d",&pCur->_val);
        pCur->next=NULL;
    }
    free(pCur);
    pCur=NULL;
    pTail->next=NULL;
    return pHead;
}

Node* Delete(Node* pHead,int _iNode)
{
    Node* pCur=pHead;
    Node* pPre=NULL;
    if(NULL==pHead){
        printf("\n\tThis is NULL!\n");
        return NULL;
    }
    while (NULL!=pCur&&pCur->_val!=_iNode)
    {
        pPre=pCur;
        pCur=pCur->next;
    }

    if (NULL==pCur)
    {
        printf("\t%d has not been Found!\n",_iNode);
        return pHead;
    }

    if (NULL==pPre)
    {
        pPre=pCur;
        pCur=pCur->next;
        pHead=pCur;
        free(pPre);
        return pHead;
    }
    pPre->next=pCur->next;
    free(pCur);
    _iNodeCout--;
    return pHead;
}

void Find(Node* pHead,int _iNode)
{
    Node* pCur=pHead;
    if(NULL==pHead){printf("\n\tThis is NULL!\n");return;}
    while ( NULL!=pCur && pCur->_val!=_iNode )
        pCur=pCur->next;

    if (NULL==pCur)printf("%d has not been found!\n ",_iNode);
    else printf("%d has been found!\n ",_iNode);
}

Node* Insert(Node* pHead,Node* insertNode)
{
    Node* pCur=pHead,* pPre=NULL;

    if (NULL==pCur)
    {
        pHead=insertNode;
        insertNode->next=NULL;
    }
    else
    {
        while (pCur!=NULL&&pCur->_val<insertNode->_val)
        {
            pPre=pCur;
            pCur=pCur->next;
        }

        if (pCur->_val>insertNode->_val)
        {
            if (NULL==pPre) //在表头插入
                pHead=insertNode;
            else
                pPre->next=insertNode;
            insertNode->next=pCur;
        }
        else   // 表尾插入
        {
            pCur->next=insertNode;
            insertNode->next=NULL;
        }
    }
    _iNodeCout++;
    return pHead;
}

void Print(Node* pHead)
{
    Node* pCur=pHead;
    if(NULL==pHead){printf("\n\tThis is NULL!\n");return;}
    puts("output is: ");
    do
    {
        printf("%d->",pCur->_val);
        pCur=pCur->next;
    } while (NULL!=pCur);
    printf("NULL");
}

// 逆转链表 -- 迭代实现
Node* Reversed(Node* pHead)
{
    Node* pCur=pHead;
    Node* pPre=NULL;
    if(NULL==pHead){printf("\n\tThis is NULL!\n");return pHead;}
    while (NULL!=pCur)
    {
        Node* pNext=pCur->next;
        //if(NULL==pNewHead) pNewHead=pPre;
        pCur->next=pPre;
        pPre=pCur;
        pCur=pNext;
    }
    return pPre;
}

// 逆转链表 -- 递归实现
Node* ReversedNode_1(Node* pHead)
{
    Node* p,* pNewHead;

    if (pHead == NULL || pHead -> next == NULL)
    {
        return pHead;
    }
    p = pHead -> next;
    pNewHead =  ReversedNode_1(p);
    p -> next = pHead;
    pHead ->next = NULL;
    return pNewHead;
}


//---------------- K 逆转链表 ----------------------
Node* KInvert(Node* pHead)
{
    Node* pCurr;
    Node* pNewHead=NULL;
    if (NULL==pHead)
        return pHead;

    while (pHead)
    {
        pCurr=pHead;
        pHead=pHead->next;
        pCurr->next=pNewHead;
        pNewHead=pCurr;
    }
    return pNewHead;
}

Node* GetLastNode(Node* pHead)
{
    while (NULL!=pHead->next)
        pHead=pHead->next;
    return pHead;
}

Node* KReversed(Node* pHead,int iK)
{
    int iPos; //
    Node* pCurr=pHead;
    Node* pNewHead;
    Node* pNextNode;
    Node* pLastNode=NULL;
    if(iK<=1) return pHead;
    pHead=NULL;

    while (pCurr)
    {
        iPos=0;
        pNewHead=pCurr;
        while (pCurr&&iPos<iK-1)
        {
            pCurr=pCurr->next;
            iPos++;
        }

        if (pCurr)
        {
            pNextNode=pCurr->next;
            pCurr->next=NULL;

            pNewHead=KInvert(pNewHead);
            if (NULL==pHead)
                pHead=pNewHead;
            else
                pLastNode->next=pNewHead;

            // 获取上面那段链表的尾节点
            pCurr=GetLastNode(pNewHead);
            pCurr->next=pNextNode;
            pLastNode=pCurr;
            pCurr=pNextNode;
        }
    }
    return pHead;
}


在一般的面试中,如果涉及到链表,很多面试官会让你写出如何将单向链表中的某个节点删除的代码或者伪码。所以如果你最近要参加面试,可着重看删除这部分,结合理论,会掌握的更好。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值