数据结构之单链表

单链表相对于顺序表来说拥有可以减少使用空间,可以更快速的对表中数据进行插入与删除的优点,而对于顺序表,查找一个元素的时间复杂度仅仅为O(1),然而单链表却需要遍历寻找。

以下是我写的单链表,功能不知完全不完全,希望大家都有一些收获吧。

/************************************************************************/
/*             以下是关于线性表链接存储(单链表)操作的14种算法        */
 
/* 1.初始化线性表,即置单链表的表头指针为空 */
/* 2.创建线性表,此函数输入零终止读取数据*/
/* 3.打印链表,链表的遍历*/
/* 4.销毁线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
/* 5.返回单链表的长度 */
/* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
/* 7.查找第i个元素,若为查找到输出提示语句,否则返回查找值*/
/*  8.查找第i个元素的前驱。*/
/*  9.查找第i个元素的后继。*/
/*  10.确定一个数的位置,若找到输出位置所在,找不到,返回提示语句。*/
/* 11.在链表中插入一个元素*/
/* 12.在链表中删除一个元素*/
/* 13.合并两个有序的链表.*/
/* 14.给定一个数,看是否可以在链表中删除。*/
FISRT:    
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int elemType;

这里是一些规定,以及需要用到的头文件。

接下来就要来看单链表的储存结构:

typedef struct Node
{
    elemType e;
    struct Node *next;
};
/* 1.初始化线性表,即置单链表的表头指针为空 */
void InitList(Node **head)
{
    *head=NULL;
    cout<<"get a empty list"<<endl;
}

/* 2.创建线性表,此函数输入零终止读取数据*/

void createList(struct Node **head)
{
    struct Node *t,*w;
    int shu;
    *head = NULL;
    cout<<"请输入一个数:(输入零终止输入) :";
    cin>>shu;
    while(shu!=0)
    {
        t=(Node *)malloc(sizeof(struct Node));
        t->e=shu;
        t->next=NULL;
        //由于没有头结点,需要判断链表首结点是否为空,若为空,就插入到首节点,不为空则插入已有节点之后。
        if(*head==NULL)
        {
            *head=t;
        }
        else
        {
            w->next=t;
        }
        w=t;
        cout<<"请输入一个数:(输入零终止输入) :";
        cin>>shu;
    }
}

/* 3.打印链表,链表的遍历*/

void visit(struct Node *head)
{
    if(head==NULL) cout<<"not exit"<<endl;//链表为空
    else//链表不为空
    {
        while(head)
        {
            if(head->next!=NULL)
                cout<<head->e<<" ";
            else
                cout<<head->e<<endl;//最后一个后面没有空格,比较严谨 
            head=head->next;
        }
    }
}

/* 4.销毁线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */

void Destroy(struct Node *head)
{
    Node *p;
    while(head!=NULL)
    {
        p=head;
        head=head->next;
        free(p);
    }
    cout<<"finish"<<endl;

}

/* 5.返回单链表的长度 */

int listlength(Node *head)//遍历的方法求长度,也可以边创建链表,边计算长度。
{
    int len=0;
    while(head!=NULL)
    {
        head=head->next;
        len++;
    }
    return len;
}

/* 6.检查单链表是否为空,若为空则返回1,否则返回0 */

elemType isEmptyList(Node *head)
{
    if(head == NULL)
    {
        cout<<"isEmptyList函数执行,链表为空
";
        return 1;
    }
    cout<<"isEmptyList函数执行,链表非空
";
    return 0;
}

/* 7.查找第i个元素,若为查找到输出提示语句,否则返回查找值*/

elemType getelem(Node *head,int pos)
{
    int i=0;
    if(pos<1) cout<<"please check input"<<endl;
    if(head==NULL)//表为空
    {
        cout<<"not exit"<<endl;
        exit(ERROR);
    }
    while(head!=NULL)
    {
        ++i;
        if(i==pos)
        {
            break;
        }
        else
        {
            head=head->next;
        }

    }
    if(i<pos)
    {
        cout<<"pos is larger than i,please check intput"<<endl;
    }
    return head->e;
}

/*  8.查找第i个元素的前驱。*/

elemType priorelem(Node *head,int pos)
{
    int i=0;
    if(pos<1) cout<<"please check input"<<endl;
    if(head==NULL)
    {
        cout<<"not exit"<<endl;
        exit(ERROR);
    }
    while(head!=NULL)
    {
        ++i;
        if(i==pos-1)
        {
            break;
        }
        else
        {
            head=head->next;
        }

    }
    if(i<pos-1)
    {
        cout<<"pos is larger than i,please check intput"<<endl;
    }
    return head->e;
}

/*  9.查找第i个元素的后继。*/

elemType nextelem(Node *head,int pos)
{
    int i=0;
    if(pos<1) cout<<"please check input"<<endl;
    if(head==NULL)
    {
        cout<<"not exit"<<endl;
        exit(ERROR);
    }
    while(head!=NULL)
    {
        ++i;
        if(i==pos+1)
        {
            break;
        }
        else
        {
            head=head->next;
        }

    }
    if(i<pos+1)
    {
        cout<<"pos is larger than i,please check intput"<<endl;
    }
    return head->e;
}

/*  10.确定一个数的位置,若找到输出位置所在,找不到,返回提示语句。*/

void locateelem(Node *head,int pos)
{
    if(head==NULL) cout<<"not exit"<<endl;
    else
    {
        int i=0,flag=0;
        while(head!=NULL)
        {
            ++i;
            if(pos==head->e)
            {
                flag=1;
                break;
            }
            head=head->next;
        }
        if(flag==1)cout<<"元素"<<pos<<"的位置为:"<<i<<endl;
        else cout<<"该链表中无此元素"<<endl;
    }
}

/* 11.在链表中插入一个元素*/

void listinsert(Node **head,int w,int n)
{
    struct Node *add;
    struct Node *jihead;
    int count=1;//计数器
    jihead = *head;
    add = (Node* )malloc(sizeof(Node));
    add->e = n;
    add->next = NULL;
    if(*head == NULL)//如果表中无数据就插入在表头
    {
        *head=add;
    }
    if(w == 1)//在第一个位置插入数据
    {
        add->next = *head;
        *head = add;
        return ;
    }
    while(jihead!=NULL)
    {
        count++;
        if(count==w)
        {
            add->next=jihead->next;
            jihead->next=add;
            return ;
        }
        jihead=jihead->next;
    }
    jihead->next=add;//最后也没找到位置,就插在末尾。
}

/* 12.在链表中删除一个元素*/

void listdelete(Node **head,int n)
{
    struct Node *dele,*jihead;
    jihead=*head;
    int count=1;//依旧还是计数器
    if(*head==NULL)
    {
        cout<<"链表为空"<<endl;
    }
    if(n==1)//删除第一位
    {
        dele=*head;
        *head=(*head)->next;
        free(dele);
    }
    while(jihead!=NULL)
    {
        count++;
        if(count==n)
        {
            dele=jihead->next;
            jihead->next=jihead->next->next;
            free(dele);
        }
        jihead=jihead->next;
    }
}

/* 13.合并两个有序的链表.*/

struct Node* SortedMerge(struct Node* a, struct Node* b)//两个单调不递减的有序序列
{
    struct Node* result = NULL;
    if(a == NULL)  return b;
    else if(b == NULL)  return a;
    /*Pick either a or b, and recur */
    if(a->e <= b->e)
    {
        result = a;
        result->next = SortedMerge(a->next, b);//递归
    }
    else
    {
        result = b;
        result->next = SortedMerge(a, b->next);
    }
    return (result);
}

/* 14.给定一个数,看是否可以在链表中删除。*/

void listdrop(Node **head,int pos)
{
    struct Node *del,*jihead;
    jihead=*head;
    if((*head)->e==pos)
    {
        del=*head;
        *head=(*head)->next;
        free(head);
    }
    else
    {
        while(jihead!=NULL)
        {
            if(jihead->next->e==pos)
            {
                 del=jihead->next;
                 jihead->next=jihead->next->next;
                 free(del);
                 return;
            }
            jihead=jihead->next;
        }
    }
}

主函数:

int main()
{

    struct Node *p1;
    struct Node *p2;
    struct Node *p3;
    createList(&p1);
    visit(p1);
    int n;
    cin>>n;
    listdrop(&p1,n);
    visit(p1);
    createList(&p2);
    visit(p2);
    p3=SortedMerge(p1,p2);
    //cout<<"length: "<<listlength(p)<<endl;
    //visit(p3);
    //cout<<"---------------"<<endl;

    //cout<<"查找第i位元素: "<<getelem(p,2)<<endl;
    //cout<<"查找第i位元素前驱: "<<priorelem(p,2)<<endl;
    //cout<<"查找第i位元素后继: "<<nextelem(p,2)<<endl;
    //locateelem(p,2);
    //listinsert(&p,3,99);
    //visit(p);
    //listdelete(&p,4);
    //visit(p);
    //InitList(&p);
    //Destroy(p);
    //visit(p);
    return 0;
}

新手博文,如有缺憾,还望指教。

原文地址:https://www.cnblogs.com/famousli/p/4227928.html