单向链表常用操作,C和C++版本(转载)

C版本

View Code
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #define DataType int
  4 #define FLAG -1
  5 typedef struct Node
  6 {
  7     DataType data;
  8     struct Node *next;
  9 }Lnode,*LinkList;
 10 
 11 LinkList Creat_LinkList()
 12 {
 13     LinkList L;
 14     Lnode *s,*r;
 15     int x;
 16     printf("建立有表头结点的单链表,以%d作为创建链表完成的标志\n",FLAG);
 17     L=r=s=NULL;
 18     L=(Lnode *)malloc(sizeof(Lnode));
 19     if(!L)
 20     {
 21         printf("表头结点开辟失败\n");
 22         exit(-1);
 23     }
 24     L->next=NULL;
 25     scanf("%d",&x);
 26     while(x!=FLAG)
 27     {
 28         s=(Lnode *)malloc(sizeof(Lnode));
 29         if(!s)
 30         {
 31             printf("结点开辟失败\n");
 32             exit(-1);
 33         }
 34         s->data=x;
 35         if(NULL==L->next)//第一个结点的处理
 36             L->next=s;
 37         else
 38             r->next=s;
 39         r=s;
 40         scanf("%d",&x);
 41     }
 42     if(r!=NULL)//对于非空表,最后结点的指针域放空指针
 43         r->next=NULL;
 44     return L;
 45 }
 46 /*有头结点的链表,求表长算法*/
 47 int Length_LinkList(LinkList L)
 48 {
 49     Lnode *p;
 50     int j;
 51     p=L;
 52     j=0;
 53     while(p->next)
 54     {
 55         p=p->next;
 56         j++;
 57     }
 58     return j;
 59 }
 60 int Print_LinkList(LinkList L)
 61 {
 62     printf("输出:\n");
 63     Lnode *s;
 64     s=L;
 65     while(s->next!=NULL)
 66     {
 67         s=s->next;
 68         printf("%3d",s->data);
 69     }
 70     printf("\n");
 71     return 0;
 72 }
 73 /*逆置算法思路:
 74 依次取原链表中每个结点,将其作为第一个结点插入到新的
 75 链表中去。指针p用来指向原表中当前结点,p为空时结束。*/
 76 void Reverse_LinkList(LinkList H)//单链表的逆置
 77 {
 78     Lnode *p,*q;
 79     p=H->next;//p指向第一个结点
 80     H->next=NULL;//将原链表置为空表
 81     while(p)
 82     {
 83         q=p;
 84         p=p->next;
 85         q->next=H->next;//将当前节点插入到头结点后面
 86         H->next=q;
 87     }
 88     return;
 89 }
 90 
 91 /*按序号查找*/
 92 Lnode *Get_LinkList(LinkList L,int i)
 93 {
 94     Lnode *p;
 95     int j=0;
 96     p=L;
 97     while(p->next!=NULL&&j<i)
 98     {
 99         p=p->next;
100         j++;
101     }
102     if(j==i)
103         return p;
104     else
105         return NULL;
106 }
107 /*按值查找*/
108 Lnode *Locate_LinkList(LinkList L,DataType x)
109 {
110     Lnode *p;
111     p=L->next;
112     while(p!=NULL&&p->data!=x)
113         p=p->next;
114     return p;
115 }
116 /*插入操作,分为:前插接点、后插结点.下面的算法实现在链表的第i个位置上插入一个数值
117 
118 后插结点:设p指向单链表中某结点,s指向待插入值为x的新结点,将*s插入到*p之后,
119 操作:s->next=p->next;p->next=s;
120 前插接点:遇红茶结点不同德是,这种算法要先找到前驱结点*q,然后完成在*q后插入*s,
121 操作:q=L;while(q->next!=p)q=p->next;s->next=q->next;q->next=s;*/
122 int Insert_LinkList(LinkList L,int i,DataType x)
123 {
124     Lnode *p,*s;
125     p=Get_LinkList(L,i-1);
126     if(NULL==p)
127     {
128         printf("前驱结点不存在,不能插入\n");
129         return 0;
130     }
131     else
132     {
133         s=(Lnode *)malloc(sizeof(Lnode));
134         s->data=x;
135         s->next=p->next;
136         p->next=s;
137         return 1;
138     }
139 }
140 
141 /*按序号删除结点*/
142 int Del_LinkList(LinkList L,int i)
143 {
144     Lnode *p,*s;
145     p=Get_LinkList(L,i-1);
146     if(NULL==p)
147     {
148         printf("你要删除的结点前驱结点不存在\n");
149         return -1;
150     }
151     else
152         if(NULL==p->next)
153         {
154             printf("第%d个结点不存在\n",i);
155             return 0;
156         }
157         else
158         {
159             s=p->next;
160             p->next=s->next;
161             free(s);
162             return 1;
163         }
164 }
165 /*按值删除结点,为了使算法清晰,只删除找到的第一个结点*/
166 int Remove_LinkList(LinkList L,DataType x)
167 {
168     Lnode *p,*s;
169     p=Locate_LinkList(L,x);//找到要删除的结点
170     if(NULL==p)
171     {
172         printf("你要删除的结点不存在\n");
173         return -1;
174     }
175     s=L;
176     while(s->next!=p)
177         s=s->next;//找到要删除结点的前驱
178     s->next=p->next;
179     free(p);
180     return 1;
181 }
182 int main()
183 {
184     Lnode *L,*p;
185     int n,m,k;
186     L=Creat_LinkList();
187     Print_LinkList(L);
188     printf("表长(头结点不计算在内):%d\n",Length_LinkList(L));
189     printf("按序号查找,请输入你要查找的结点的序号:\n");
190     scanf("%d",&n);
191     p=Get_LinkList(L,n);
192     if(NULL==p)
193         printf("未找到\n");
194     else
195         printf("找到了,该结点存放的数据:%d\n",p->data);
196     printf("按值查找,请输入你要查找的数据:\n");
197     scanf("%d",&n);
198     p=Locate_LinkList(L,n);
199     if(NULL==p)
200         printf("未找到\n");
201     else
202         printf("找到了\n");
203     printf("插入结点,请输入你要插入的位置和数值\n");
204     scanf("%d%d",&k,&n);
205     m=Insert_LinkList(L,k,n);
206     if(0==m)
207         printf("前驱结点不存在不能插入\n");
208     else if(1==m)
209         printf("插入成功\n");
210     Print_LinkList(L);
211     printf("表长(头结点不计算在内):%d\n",Length_LinkList(L));
212     printf("按序号删除,请输入你要删除的结点的序号:\n");
213     scanf("%d",&n);
214     m=Del_LinkList(L,n);
215     if(-1==m)
216         printf("你要删除的结点无前驱结点\n");
217     else if(0==m)
218         printf("你要删除的结点不存在\n");
219     else if(1==m)
220         printf("删除成功\n");
221     Print_LinkList(L);
222     printf("表长(头结点不计算在内):%d\n",Length_LinkList(L));
223     printf("按值删除,请输入你要删除的数据:\n");
224     scanf("%d",&n);
225     m=Remove_LinkList(L,n);
226     if(-1==m)
227         printf("你要删除的结点无前驱结点\n");
228     else if(0==m)
229         printf("你要删除的结点不存在\n");
230     else if(1==m)
231         printf("删除成功\n");
232     Print_LinkList(L);
233     printf("表长(头结点不计算在内):%d\n",Length_LinkList(L));
234     Reverse_LinkList(L);
235     printf("逆置后:\n");
236     Print_LinkList(L);
237     return 0;
238 }

C++版本

//File: LinkNode.h
//Author: Jason

#ifndef LINKNODE_H_
#define LINKNODE_H_

template<typename Type>

struct LinkNode//结点类定义
{
    Type data;//数据元素
    LinkNode<Type> *pnext;//链表指针域
    //构造函数
    //仅初始化指针成员的构造函数
    LinkNode(LinkNode<Type> *next = NULL):pnext(next){}
    //初始化数据和指针成员的构造函数
    LinkNode(const Type &item, LinkNode<Type> *next = NULL):data(item),pnext(next){}
};

#endif
View Code
//File: SingleLinkList.h
//Author: Jason

#ifndef SINGLELINKLIST_H_
#define SINGLELINKLIST_H_

#include<iostream>
using namespace std;
#include<assert.h>
#include<stdlib.h>

#include"LinkNode.h"

template<typename Type>
class SingleLinkList//单链表定义
{
public:
    //构造函数
    SingleLinkList(LinkNode<Type> *node = NULL):phead(new LinkNode<Type>(node)){ }
    SingleLinkList(Type & x){ phead = new LinkNode<Type>(x);}
    SingleLinkList(SingleLinkList &list);//复制构造函数
    ~SingleLinkList(){ setEmpty();}//析构函数

public:
    LinkNode<Type> *getHead(){ return phead; }//返回链表的头结点
    LinkNode<Type> *getRear();//获得链表的尾结点
    LinkNode<Type> *Locate(int i);//搜索第i个元素的地址
    LinkNode<Type> *Search(const Type &x);//搜索含数据x的元素
    void setEmpty();//将链表设置为空
    int getlength()const;//计算链表的长度
    //判断表是否为空,空则返回true
    bool isEmpty()const{ return phead->pnext == NULL ? true : false; }
    bool isFull()const{ return false;}//判断表是否为满,满则返回false
    bool getData(int i, Type &x);//取出第i个元素的值
    bool setData(int i, Type &x);//用x修改第i个元素的值
    bool Insert(Type &x,int i=0);//在第i个元素后插入x
    bool Remove(Type &x,int i=0);//删除第i个元素,x返回该元素的值
    bool InsertHead(Type &x);//在第1个元素前插入x,即有头结点之后插入
    bool InsertRear(Type &x);//在链表的最后后插入x
    bool RemoveHead(Type &x);//将链表中的最后一个元素删去,通过引用型参数x返回该元素的值
    bool RemoveRear(Type &x);//将链表中的最后一个元素删去,通过引用型参数x返回该元素的值

    void output()const;//输出链表中的元素

    SingleLinkList<Type> &operator=(SingleLinkList &list);//赋值重载函数
    //友元函数,操作符重载
    friend ostream& operator<<<Type>(ostream& os,const SingleLinkList<Type>& list);
private:
    LinkNode<Type> *phead;//声明头结点
};
template<typename Type>
SingleLinkList<Type>::SingleLinkList(SingleLinkList<Type> &list)//复制构造函数
{
    Type value;
    LinkNode<Type> *srcnode = list.getHead();//被复制的附加头结点地址
    LinkNode<Type> *destnode = new LinkNode<Type>();
    while(srcnode->pnext!=NULL)//逐个结点复制
    {
        value = srcnode->pnext->data;
        destnode->pnext = new LinkNode<Type>(value);
        destnode = destnode->pnext;
        srcnode = srcnode->pnext;
    }
    destnode->pnext = NULL;
}
template<typename Type>
void SingleLinkList<Type>::setEmpty()//将链表设置为空
{
    LinkNode<Type> *pDel;
    while(phead->pnext!=NULL)//当链表不为空时删去链表中所有结点
    {
        pDel = phead->pnext;//保存被删除的结点,从链上取下该结点
        phead->pnext = pDel->pnext;//删除,仅保留头结点
        delete pDel;
    }
}
template<typename Type>
int SingleLinkList<Type>::getlength() const//计算带附加结点的单链表的长度
{
    LinkNode<Type> *pMove = phead->pnext;
    int nCount = 0;
    while(pMove!=NULL)//链表扫描,寻找链尾
    {
        nCount++;
        pMove = pMove->pnext;
    }
    return nCount;
}
template<typename Type>
LinkNode<Type> *SingleLinkList<Type>::getRear()//获得链表的尾结点
{
    LinkNode<Type> *pMove = phead;
    while(pMove->pnext!=NULL)
    {
        pMove = pMove->pnext;
    }
    return pMove;
}
template<typename Type>
LinkNode<Type> *SingleLinkList<Type>::Locate(int i)
{//定位函数,返回表中第i个元素的地址,若i<0或i超出表中结点个数,则返回NULL
    if( i < 0 ) return NULL;//i不合理
    LinkNode<Type> *pMove = phead;
    int k = 0;
    while(pMove->pnext!=NULL && k<i)//寻找第i个结点
    {
        pMove = pMove->pnext;
        k++;
    }
    //返回第i个结点地址,若返回NULL,表示i值太大或太小
    return pMove;
}

template<typename Type>
LinkNode<Type> *SingleLinkList<Type>::Search(const Type &x)
{//在表中搜索含数据x的结点,搜索成功时函数返回该结点的地址,否则返回NULL值
    LinkNode<Type> *pCurrent = phead->pnext;
    while(pCurrent==NULL)
    {
        if(pCurrent->data != x)//循环链找含x的结点
            break;
        else
            pCurrent = pCurrent->pnext;   
    }
    return pCurrent;
}

template<typename Type>
bool SingleLinkList<Type>::getData(int i, Type &x)
{//取出链表中第i个元素的值
    LinkNode<Type> *pCurrent = Locate(i);
    if(pCurrent==NULL||pCurrent==phead) return false;//i不合理
    x = pCurrent->data;
    return true;
}

template<typename Type>
bool SingleLinkList<Type>::setData(int i, Type &x)
{//给链表中第i个元素赋值
    LinkNode<Type> *pCurrent = Locate(i);
    if(pCurrent==NULL||pCurrent==phead) return false;//i不合理
    pCurrent->data = x;
    return true;
}

template<typename Type>
bool SingleLinkList<Type>::Insert(Type &x, int i)//在第i个元素后插入x
{
    LinkNode<Type> *pCurrent = Locate(i);
    if(pCurrent==NULL) return false;
    LinkNode<Type> *newNode = new LinkNode<Type>(x);
    assert(newNode!=NULL);
    newNode->pnext = pCurrent->pnext;
    pCurrent->pnext = newNode;
    return true;
}
template<typename Type>
bool SingleLinkList<Type>::InsertHead(Type &x) //即insert(0,x)
{//在第1个元素前插入x,即有头结点之后插入
    LinkNode<Type> *newNode = new LinkNode<Type>(x);
    assert(newNode!=NULL);
    newNode->pnext = phead->pnext;
    phead->pnext = newNode;
    return true;
}

template<typename Type>
bool SingleLinkList<Type>::InsertRear(Type &x)
{//在链表的最后后插入x
    LinkNode<Type> *prear = getRear();
    LinkNode<Type> *newNode = new LinkNode<Type>(x);
    assert(newNode!=NULL);
    newNode->pnext = prear->pnext;
    prear->pnext = newNode;
    return true;
}

template<typename Type>
bool SingleLinkList<Type>::Remove(Type &x, int i)
{//将链表中的第i个元素删去,通过引用型参数x返回该元素的值
    LinkNode<Type> *pCurrent = Locate(i-1);
    if(pCurrent==NULL||pCurrent->pnext==NULL) return false;
    LinkNode<Type> *pDel;
    pDel = pCurrent->pnext;//重新拉链,将被删除的结点从链表中取出
    pCurrent->pnext = pDel->pnext;
    x = pDel->data;//取出被删除结点中的数据值
    delete pDel;
    return true;
}
template<typename Type>
bool SingleLinkList<Type>::RemoveHead(Type &x)
{//将链表中的第1个元素删去,通过引用型参数x返回该元素的值
    LinkNode<Type> *pDel;
    if(phead->pnext==NULL) return false;
    pDel = phead->pnext;
    phead->pnext = pDel->pnext;
    x = pDel->data;
    delete pDel;
    return true;
}
template<typename Type>
bool SingleLinkList<Type>::RemoveRear(Type &x)
{//将链表中的最后一个元素删去,通过引用型参数x返回该元素的值
    if(phead->pnext==NULL) return false;
    LinkNode<Type> *pCurrent = phead;
    while(pCurrent->pnext->pnext!=NULL)
    {
        pCurrent = pCurrent->pnext;
    }
    LinkNode<Type> *pDel;
    pDel = pCurrent->pnext;
    pCurrent->pnext = pDel->pnext;
    x = pDel->data;
    delete pDel;
    return true;
}

template<typename Type>
void SingleLinkList<Type>::output()const//输出链表中的元素
{
    LinkNode<Type> *pMove = phead;
    cout << "Head->";
    while(pMove->pnext!=NULL)
    {
        pMove = pMove->pnext;
        cout << pMove->data << "->";
    }
    cout << "End" << endl;
}

template<typename Type>
SingleLinkList<Type> &SingleLinkList<Type>::operator=(SingleLinkList &list)
{//操作符重载
    Type value;
    LinkNode<Type> *srcnode = list.getHead();
    LinkNode<Type> *destnode = new LinkNode<Type>();
    while(srcnode->pnext!=NULL)
    {
        value = srcnode->pnext->data;
        destnode->pnext = new LinkNode<Type>(value);
        destnode = destnode->pnext;
        srcnode = srcnode->pnext;
    }
    destnode->pnext = NULL;
    return *this;
}
template<typename Type>
ostream& operator<<(ostream& os,SingleLinkList<Type>& list) //友元函数,操作符重载
{//输出链表中元素的重载操作符<<
    os << "The length of the list is: " << list.getlength() << endl; // the size of stack is ouputing!
    LinkNode<Type> *pMove = list.getHead();
    os << "Head->";
    while(pMove->pnext!=NULL) //The menmber of the stack is outputing respectively!
    {
        pMove = pMove->pnext;
        os <<  pMove->data <<  "->";
    }
    os << "End" << endl;
    return os;
}
#endif
View Code
//Fle: Main.cpp
//Author: Jason

#include<iostream>
#include"SingleLinkList.h"
using namespace std;

int main()
{
    SingleLinkList<int> list;
    list.setEmpty();
    //测试空链表的长度
    cout << "The length of the list is " << list.getlength() << endl;
    if(list.isEmpty())
        cout << "The list is Empty! " << endl;
    else
        cout << "The list is Not Empty! " << endl;
    //向链表表中插入元素
    for(int i=0; i<10; i++)
    {
        int temp = 2*i;
        list.Insert(temp,i);
        cout << temp << " has been inserted ! \n";
        cout << "Output the list:\n";
        list.output();
        cout << "The length of the list is " << list.getlength() << endl;
        cout << endl;
    }
    //查看特定位置的元素并进行修改
    int data;
    list.getData(5,data);
    cout << "The fifth number in the list is " << data << endl;
    data = 100;
    list.setData(5,data);
    list.output();
    cout << "The fifth number in the list is modfied by " << data << endl;
    cout << endl;
    //删除链表元素
    for(int i=10; i>0; i--)
    {
        int temp = 0;
        list.Remove(temp,i);
        cout << temp << " has been deleted ! \n";
        cout << "Output the list:\n";
        list.output();
        cout << "The length of the list is " << list.getlength() << endl;
        cout << endl;
    }
    //向链表利用前插法在链表头部插入元素
    for(int i=0; i<5; i++)
    {
        int temp = 3*i;
        list.InsertHead(temp);
        cout << temp << " has been inserted at the head ! \n";
        cout << "Output the list:\n";
        list.output();
        cout << "The length of the list is " << list.getlength() << endl;
        cout << endl;
    }
    //向链表利用后插法在链表的尾部插入元素
    for(int i=0; i<5; i++)
    {
        int temp = 3*i;
        list.InsertRear(temp);
        cout << temp << " has been inserted at the end ! \n";
        cout << "Output the list:\n";
        list.output();
        cout << "The length of the list is " << list.getlength() << endl;
        cout << endl;
    }
    //从链表头部开始删除元素
    for(int i=0; i<5; i++)
    {
        int temp;
        list.RemoveHead(temp);
        cout << temp << " has been deleted ! \n";
        cout << "Output the list:\n";
        list.output();
        cout << "The length of the list is " << list.getlength() << endl;
        cout << endl;
    }
    //从链表尾部开始删除元素
    for(int i=0; i<5; i++)
    {
        int temp;
        list.RemoveRear(temp);
        cout << temp << " has been deleted ! \n";
        cout << "Output the list:\n";
        cout << list;
        cout << endl;
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/alanlau2011/archive/2012/06/16/2551643.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值