单链表的建立,实现和操作

文中引用了一个单链表就地逆序的算法,在下资质愚钝想了半天没想出来,感谢这位仁兄的分享 点击打开链接
#include
#include
#include
#include
#include
using namespace std;
typedef struct LNode
{
    int data;
    struct LNode *next;
} LinkList;
//注意,单链表头节点不保存数据
void InitList(LinkList *&head)//初始化单链表
{
    head=(LinkList*)malloc(sizeof(LinkList));
    head->next=NULL;
}
//下面是两种创建单链表的方法
//其中头节点为head融合在创建中,因提前建立,所以下方不使用
void CreateListA(LinkList *&head,int a[],int n)//尾插法,依次将元素放在前一个元素后方
{
    LinkList *r,*s;//建立两个指针
    /*head=(LinkList*)malloc(sizeof(LinkList));//为头结点分配空间
    head->next=NULL;*/
    r=head;
    for(int i=0; idata=a[i];
        r->next=s;
        r=s;//是r不断更新为所插入的下一个元素,再次进入循环
    }//通过for循环实现尾插法
    r->next=NULL;
}
void CreateListB(LinkList *&head,int a[],int n)//头插法,逻辑顺序与物理顺序相反
{
    LinkList *s;
    /*head=(LinkList*)malloc(sizeof(LinkList));//分配空间
    head->next=NULL;*/
    s=head;
    for(int i=0; idata=a[i];
        s->next=head->next;
        head->next=s;//元素在插入的过程中新元素排在旧元素后面,所以逻辑物理顺序相反
    }
}
void DestroyList(LinkList *&head)//销毁单链表
{
    LinkList *pre=head,*p=head->next;//创建两个指针,来回使用
    while(p!=NULL)
    {
        free(pre);
        pre=p;
        p=pre->next;
    }//逐一释放空间
    free(pre);//释放最后一个
}
bool ListEmpty(LinkList *&head)//判断是否为空表(是否只含有一个头节点,若是,则为空)
{
    return (head->next==NULL);//如果为空,则返回值为1
}
int ListLength(LinkList *head)//计算单链表长度
{
    int n=0;
    LinkList *p=head;
    while(p->next!=NULL)
    {
        n++;
        p=p->next;
    }
    return n;
}
void DisplayList(LinkList *head)//输出线性表各个元素
{
    LinkList *p=head->next;//由于头节点不保存数据,所以从下一个开始
    while(p!=NULL)
    {
        cout<data<<' ';
        p=p->next;
    }
    cout<next;
    }
    if(p==NULL)//判断循环中断的原因,若为p==NULL,则说明超出单链表范围
        return false;
    else
    {
        e=p->data;
        return true;
    }
}
int  LocateElem(LinkList *head,int e)//找出哪一个位置的元素与e值相等,若不存在,输出0
{
    LinkList *p=head->next;
    int i;
    for(i=1; p!=NULL&&p->data!=e; i++)
    {
        p=p->next;
    }
    if(p==NULL)//判断终止条件
        return 0;//代表不存在,遍历完毕
    else
        return i;
}
/*下面是单链表的插入和删除操作,可以借用if判断来得出插入或删除值。
   也可直接调用函数*/
bool ListInsert(LinkList *&head,int i,int e)//插入元素在第i个位置插入元素e
{
    LinkList *p=head,*s;
    for(int j=0; jnext;
    }
    if(p==NULL)
        return false;
    else
    {
        s=(LinkList*)malloc(sizeof(LinkList));
        s->data=e;
        s->next=p->next;
        p->next=s;//画图吧,画图好理解
        return true;
    }
}
bool ListDelete(LinkList *&head,int i,int &e)//删除线性表第i个元素,将删除元素的值赋给e
{
    LinkList *p=head,*q;
    for(int j=0; jnext;
    }
    if(p==NULL)
        return false;
    else
    {
        q=p->next;
        if(q==NULL)//判断p下一个节点是否为空,若为空则不满足条件
            return false;
        e=q->data;//将要删除的元素赋给e
        p->next=q->next;
        free(q);
        return true;
    }
}
void nixv(LinkList *&head)//就地逆序
{
   LinkList *p,*r;//
   p=head->next;
   head->next=NULL;
   while(p!=NULL)
   {
       r=p->next;
       p->next=head->next;
       head->next=p;
       p=r;//此处关键,建议画图
   }
}
//以下是函数调用测试
int main()
{
    LinkList *head;//初定义
    InitList(*&head);//头节点
    cout<>n;
    int m;
    int a[100];
    for(int i=0; i>a[i];
    }
    CreateListA(*&head,a,n);//此处为尾插,头插用法与此相同
    //个人认为可以用不断插入的方法,这样可以动态分配内存,不用提前开数组依次填入
    DisplayList(*&head);//输出测试
    cout<<"元素个数为"<>z>>e;
    ListInsert(*&head,z,e);//插入测试
    DisplayList(*&head);//输出测试
    int qq;
    cout<<"请输入qq,代表删除第几位置的元素"<>qq;
    int zz;
    ListDelete(*&head,qq,zz);
    DisplayList(*&head);//输出测试
    cout<<"删除的元素是"<

你可能感兴趣的:(数据结构)