#ifndef _SLIST_H
#define _SLIST_H

#ifdef __cplusplus
extern "C" {
#endif

    /*******1. 不带头结点的单链表*****/


    /*****
    *@链表结点结构定义
    *@ m_data:数据
    *@m_pNext:指向下一结点的指针
    ***/
    struct listNode
    {
        int m_data;
        listNode* m_pNext;
    };
    /*******
    *@ 用数组array初始化链表,数组元素个数为n
    *@ 返回链表头
    *@auther:spf
    *@version 1.0
    *@data:2015.7.18
    */
    listNode* buildList(int* array, int n);
    /***************
    *@ 链表末尾加入一个数据
    *@pHead:指向链表头的指针
    *@value:要加入的数据 
    */
    void AddDataToTrial(listNode** pHead, int value);
    /*****************
    *单链表插入操作
    *pHead :指向表头的指针
    *@ 要插入元素的位置
    *@ 要出入的元素
    */
    bool insertList(listNode** pHead, int index, int value);
    /*****************
    *单链表删除操作
    *pHead :指向表头的指针
    *@ 要要删除元素的索引
    */
    bool deleteList(listNode** pHead, int index);

    /******************
    * 打印单链表
    @ pHead  表头指针
    */
    bool printList(listNode* pHead);



    /*******2. 带头结点的单链表*****/

    /******
    *链表的初始化
    * &pHead 链表头指针的引用
    **/
    bool initList(listNode* &pHead);

    /******
    *用数组建立链表
    * &pHead 链表头指针的引用
    **/
    bool BuildList(listNode* &pHead,int *array,int n);

    /******
    *清空链表
    * &pHead 链表头指针的引用
    **/
    bool clearList(listNode* &pHead);

    /******
    *计算表的长度
    * &pHead 链表头指针的引用
    **/
    int  lengthOfList(listNode* &pHead);

    /******
    *推断链表是否为空,空返回1。否则返回0
    * &pHead 链表头指针的引用
    **/
    bool  isEmptyOfList(listNode* &pHead);

    /******
    *查找指定元素,查找成功返回元素所在结点指针,否则返回NULL
    * &pHead 链表头指针的引用
    **/
    listNode*  searchElement(listNode* &pHead,int x);
    /******
    *在单链表中对第i(i>=0)个结点定位。函数返回第i个结点的地址,
    * 若i小于0 或i 超出结点个数,则返回NULL
    * &pHead 链表头指针的引用
    **/
    listNode*  Locate(listNode* &pHead, int i);

    /******
    *将元素value插入到链表中第i(i>=1)个结点的位置。若i不符合要求。则返回0 ,否则返回1 
    * 若i小于0 或i 超出结点个数,则返回NULL
    * &pHead 链表头指针的引用
    **/
    bool  Insert(listNode* &pHead,int i, int value);

    /******
    *将删除链表中第i(i>=1)个结点的元素,若i不符合要求,则返回0 。否则返回1,其删除的元素置于value返回
    * 若i小于0 或i 超出结点个数,则返回NULL
    * &pHead 链表头指针的引用
    **/
    bool  Remove(listNode* &pHead, int i, int &value);

    /******
    *按顺序打印打印链表
    * &pHead 链表头指针的引用
    **/
    bool  Print(listNode* &pHead);

    /******
    *递归打印链表
    * pHead 链表头指针的引用
    **/
    bool  recursivePrint(listNode* first);

    /******
    *反向打印链表(基于栈实现)
    * &pHead 链表头指针的引用
    **/
    bool  PrintListReverse(listNode* first);

    /******
    *反向打印链表(基于递归)
    * &pHead 链表头指针的引用
    **/
    bool  PrintListReverseRecursive(listNode* first);

    /******
    *反转单链表(用三个辅助指针反转)
    * &pHead 链表头指针的引用
    **/
    bool  ReverseSlist(listNode*& pHead);

    /******
    *反转单链表(递归)
    * &pHead 链表头指针的引用
    **/
    listNode*  ReverseSlistRecursive(listNode* pHead);

#ifdef __cplusplus
    }
#endif

#endif
#include "stdafx.h"
#include "slist.h"
#include <stack>
#include <stdlib.h>
#include <iostream>
/*******不带头结点的单链表*****/
listNode* buildList(int* array, int n){
    listNode*t, *pHead= new listNode();
    pHead->m_data = array[0];
    pHead->m_pNext = NULL;
    t = pHead;//取链表头
    for (size_t i = 1; i < n;++i)
    {
        listNode* pNode = new listNode();
        t->m_pNext = pNode;
        pNode->m_data = array[i];
        pNode->m_pNext=NULL;//设置尾结点的指针为空
        t = pNode;
    }
    return pHead;//返回链表头结点
}

void AddDataToTrial(listNode** pHead, int value)
{
    listNode* pNew = new listNode();
    pNew->m_data = value;
    pNew->m_pNext = NULL;
    if (*pHead == NULL)
        *pHead = pNew;//当链表为空时,新插入的结点就是链表的头指针
    else
    {
        listNode* pNode = *pHead;//取头指针
        while (pNode->m_pNext!=NULL)
        {
            pNode = pNode->m_pNext;
        }
        pNode->m_pNext = pNew;//指向新的结点
    }
}
bool insertList(listNode** pHead, int index, int value)
{
    if (index < 1)
    {
        std::cerr << "索引无效" << std::endl;
        return 0;
    }
    else if (index == 1)
    {

        //新建结点
        listNode* pNew = new listNode();
        if (pNew == NULL)
        {
            std::cerr << "分配内存失败" << std::endl;
            return 0;
        }
        pNew->m_data = value;
        pNew->m_pNext =*pHead;
        *pHead = pNew;
        //插入结点
    }
    else
    {
        listNode *pNode = *pHead;//记录第二个元素的地址
        while (pNode != NULL && 0 < index - 2)
        {
            pNode = pNode->m_pNext;
            --index;
        }

        if (pNode==NULL&&(*pHead)!=NULL)
        {
            std::cerr << "链表长度不够,无法插入" << std::endl;

            return 0;
        }
        else
        {
            //新建结点
            listNode* pNew = new listNode();
            if (pNew == NULL)
            {
                std::cerr << "分配内存失败" << std::endl;
                return 0;
            }
            pNew->m_data = value;
            //插入结点
            pNew->m_pNext = pNode->m_pNext;
            pNode->m_pNext = pNew;//插入新结点

        }

    }

    return 1;//插入成功

}
bool deleteList(listNode** pHead, int index)
{
    if (index < 1)
    {
        std::cerr << "元素索引小于1。无法进行删除操作!" << std::endl;
        return 0;
    }
    if (index == 1)
    {
        listNode* pNode = *pHead;
        *pHead = (*pHead)->m_pNext;
        delete pNode;
        pNode = NULL;
    }
    else
    {
        listNode* pNode = *pHead;
        while (pNode != NULL && 0 < index - 2)//定位第i-1个结点
        {

            pNode = pNode->m_pNext;
            --index;
        }
        if (pNode==NULL||pNode->m_pNext==NULL)
        {
            std::cerr << "空表或链表较短,索引无效"<<std::endl;
            return 0;
        }
        else
        {
            listNode *q = pNode->m_pNext;
            pNode->m_pNext = q->m_pNext;
            delete q;
            q = NULL;
        }
    }
    return 1;
}
bool printList(listNode* pHead)
{
    listNode* pNode = pHead;
    int i = 0;
    while (pNode != NULL)
    {
        ++i;
        std::cout << "第" << i << "个元素为:" << pNode->m_data << std::endl;
        pNode = pNode->m_pNext;//指向下一个元素
    }
    std::cout << "总计" << i << "个元素打印完成" << std::endl;
    return 1;
}
bool ReverseSlist(listNode*& pHead)
{
    if(pHead==nullptr&&pHead->m_pNext==nullptr)//链表为空或链表仅仅有一个元素
        return 0;
    listNode* pre, *temp, *head;//pre 指向前结点 temp 指向现结点,head 指向下一结点
    pre = temp = nullptr;
    head = pHead;
    while (head!=nullptr)
    {
        temp = head;//跟进当前结点
        head = head->m_pNext;//指向下一结点
        temp->m_pNext = pre;//反转当前结点
        pre = temp;//更新前一结点
    }
    pHead = temp;//返回翻转后的链表

    if (temp == nullptr)
        return 0;
    return 1;
}

listNode* ReverseSlistRecursive(listNode* pHead)
{
    if (pHead == nullptr || pHead->m_pNext == nullptr)//链表为空或链表仅仅有一个元素
        return pHead;
    else
    {
        listNode* newNode = ReverseSlistRecursive(pHead->m_pNext);
        pHead->m_pNext->m_pNext = pHead;
        pHead->m_pNext = nullptr;
        return newNode;
    }

}
/*******带头结点的单链表*****************/


bool initList(listNode* &pHead)
{
    pHead = new listNode;
    if (!pHead)
    {
        std::cerr << "内存分配失败" << std::endl;
        return 0;
    }
    pHead->m_pNext = NULL;//初始化矩阵头
    return 1;
}

bool BuildList(listNode* &pHead, int *array, int n)
{
    listNode* p = pHead;
    if (p == NULL)
    {
        std::cerr << "链表头不存在" << std::endl;
        return 0;
    }
    for (int i = 0; i < n;i++)
    {
        listNode* pNew = new listNode;
        pNew->m_data = array[i];
        pNew->m_pNext = NULL;
        p->m_pNext = pNew;
        p = p->m_pNext;
    }
    return 1;
}
bool clearList(listNode* &pHead)
{
    listNode* p;
    while (pHead->m_pNext!=NULL)//当链表不空时
    {
        p = pHead->m_pNext;
        pHead->m_pNext = p->m_pNext;
        delete p;
    }
    return 1;
}
int lengthOfList(listNode* &pHead)
{
    int cout = 0;
    listNode* p = pHead->m_pNext;
    while (p!=NULL)
    {
        ++cout;
        p = p->m_pNext;
    }
    return cout;
}
bool isEmptyOfList(listNode* &pHead)
{
    return (pHead->m_pNext==NULL);
}

listNode* searchElement(listNode* &pHead, int x)
{
    listNode* p = pHead->m_pNext;//取出链表头指针
    while (p != NULL&&p->m_data != x)
    {
        p = p->m_pNext;
    }
    return p;
}

listNode* Locate(listNode* &pHead, int i)
{
    if (i < 0)
        return NULL;
    listNode* p = pHead;
    int cout = 0;
    while (p!=NULL&&cout<i)
    {
        p = p->m_pNext;
        cout++;
    }
    return p;
}

bool Insert(listNode* &pHead,int i, int value)
{
    listNode* p = pHead;
    int cout = 0;
    while (p!=NULL&&cout<i-1)
    {
        cout++;
        p = p->m_pNext;
    }
    if (p == NULL||i<1)
    {
        std::cerr << "链表为空或者索引无效" << std::endl;
        return 0;
    }

    listNode* pNew = new listNode();
    pNew->m_data = value;
    pNew->m_pNext = p->m_pNext;

    p->m_pNext = pNew;
    return 1;
}
bool Remove(listNode* &pHead, int i, int &value)
{
    listNode* p = pHead;
    int cout = 0; 
    while (p!=NULL&&cout<i-1)//取出第i-1个结点指针
    {
        p = p->m_pNext;
        cout++;
    }
    if (p == NULL || p->m_pNext==NULL||i < 1)
    {
        std::cerr << "链表为空或者索引无效" << std::endl;
        return 0;
    }
    listNode* d = p->m_pNext;//第i个结点指针
    p->m_pNext = d->m_pNext;
    value = d->m_data;
    delete d;
    d = NULL;
    return 1;
}

bool Print(listNode* &pHead)
{
    if (pHead == NULL||pHead->m_pNext==NULL)
    {
        std::cerr << "链表头不存在或链表为空" << std::endl;
        return 0;
    }
    listNode* p = pHead->m_pNext;
    int cout = 0;
    while (p!=NULL)
    {
        cout++;
        std::cout << "第" << cout << "个元素为" << p->m_data << std::endl;
        p = p->m_pNext;
    }
    return 1;
}

bool recursivePrint(listNode* first)
{
    if (first == NULL)
        return 0;
    std::cout << first->m_data << std::endl;
    recursivePrint(first->m_pNext);
}

bool PrintListReverse(listNode* first)
{
    listNode* p = first;
    std::stack<listNode*> nodes;
    while (p != NULL)
    {
        nodes.push(p);
        p = p->m_pNext;
    }
    while (!nodes.empty())
    {
        p = nodes.top();
        std::cout << p->m_data << std::endl;
        nodes.pop();
    }
    return 1;
}

bool PrintListReverseRecursive(listNode* first)
{
    listNode* p = first;
    if (p != NULL)
    {
        if (p->m_pNext != NULL)
        {
            PrintListReverseRecursive(p->m_pNext);
        }
        std::cout << p->m_data << std::endl;
    }

    return 1;

}
// list.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "slist.h"
#include <cstdlib>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    int array[] = { 1, 2, 3,4 };
    listNode* list = buildList(array,4);
    //initList(list);
    //BuildList(list,array, 4);
    //1/測试用例
    // 1.索引小于1
    /*listNode* list=new listNode();
    list->m_data=0;
    list->m_pNext=NULL;*/
    /*list=NULL;
    if(NULL==list)
        cout<<"空指针"<<endl;*/
    //insertList(&list,0,0);
    //2. 链表为空。索引大于1
    //insertList(&list, 2, 0);
    //3. 链表为空。索引为1
    //insertList(&list, 1, 0);
    //4.链表不为空,索引为1
    //insertList(&list, 1, 0);
    //5.链表不为空。索引小于等于连边长度+1
    //insertList(&list, 2, 0);
    //6. 链表不为空。索引大于链表长度+1,无法插入
    //insertList(&list, 6, 5);
    //Insert(list, 5, 5);
    /*listNode* f = Locate(list, 5);
    if (f==NULL)
       std::cout << "元素不存在"<< std::endl;
    else
      std::cout<<f->m_data<<std::endl;*/

    //Print(list);
    //recursivePrint(list->m_pNext);
    //PrintListReverse(list);
    //PrintListReverseRecursive(list);
    //ReverseSlist(list);
    listNode* list2 = ReverseSlistRecursive(list);
    printList(list2);
    system("pause");

    return 0;
}