链表的定义及其基本运算

由于链表的描述比较复杂,故此处仅贴出代码,并附上本人遇到的部分问题,以供学习参考之用。

#include<iostream>
using namespace std;

typedef struct tagNode{
    int data;
    tagNode* next;
}node;
/*
该结点可看成是**存放了数值域data和指针域next的递归定义的指针**
原来的结点声明报错。
出错原因为:typedef相当于为struct结构声明了一个新的名字,如:typedef int INT;则可令INT = 4;
而此代码并未给新的名字“赋值”。最让人无法忍受的事情是,此代码系本人教材源码,坑人!在新的声明中,
我们给struct赋予了新的名字tagNode,并用tagNode定义了结点node。(注:此说明是个人理解,仅作参考)
typedef struct{
    int data;
    node* next;
}node;
*/
class list{
public:
    list();
    ~list();
    int length();
    int get_element(int i,int& x);
    node* locate(int x);
    void insert(int i,int x);
    int delete_element(int i);
    node* get_head(){return head;}
    void create_R();
    void PrintList();
private:
    int count;
    node* head;      //声明头结点
};

list::list()
{
    head = new node;   //为头结点开辟空间
    head -> next = NULL;   //将其指针置为空指针
    count = 0;
}

int list::length()   //另一简单的做法为:return count;
{
    int i = 0;
    node* p = head -> next;
    while(p != NULL){
        p = p -> next;
        i ++;
    }
    return i;
}

int list::get_element(int i,int& x)  //取得i号元素的值,并放入x中
{
    node* p;    //声明新结点p
    p = head -> next;
    int j = 1;
    while(p != NULL&&j != i){
        p = p -> next;
        j ++;
    }
    if(p == NULL)
        return -1;
    x = p -> data;  
    return 0;
}

node* list::locate(int x)  //将指针作为返回类型
{
    node* p;
    p = head -> next;
    while(p){
        if(p -> data == x)
            return p;
        else
            p = p -> next;
    }
    return NULL;
}

void list::insert(int i,int x)  //调用该函数无法运行,怀疑是内存分配问题,但不知道如何修改
{
    node* p;
    /*head = new head;     该语句导致了一个意想不到的错误,因为head在构造函数中已经被初始化了,
                           在这里重新分配内存,会报错。*/
    p = head;
    int j = 0;
    while(p || j != i - 1){
        p = p -> next;
        j ++;
    }
    if(i < 1 || i > count + 1)
        return ;
    node* s = new node;
    s -> data = x;
    s -> next = p -> next;
    p -> next = s;
    count ++;
}

int list::delete_element(int i)//与上一函数问题相同
{
    node* p;
    p = head;
    int j = 0;
    while(p || j != i){
        p = p -> next;
        j ++;
    }
    if(i < 1 || i > count + 1)
        return -1;
    node* u = new node;
    u = p -> next;
    p -> next = u -> next;
    delete u;
    count --;
    return 0;
}

list::~list() //释放指针
{
    node* p;
    p = head -> next;
    while(p)
        delete p;
}

void list::create_R()  //尾插法建立链表
{
    node *s,* rear = NULL;
    int x;
    cin>>x;
    rear = head;
    int flag = 0;
    while(x != -1){   //以-1作为结束标志
        count ++;
        s = new node;
        if(flag == 0){   /*一开始没有该if语句,亦出现insert函数的错误,是因为head没有指向s,
                            即该链表没有头结点。解决方法为:设置一标志flag,第一次循环时就执
                            下来的循环永远都不会再执行它。这种思想很重要,要mark一下*/
            head -> next = s;
            flag = 1;
        }
        s -> data = x;
        rear -> next = s;
        rear = s;
        rear -> next = NULL;
        cin>>x;
    }
}

void list::PrintList()
{
    node* p;
    p = head -> next;
    while(p != NULL){
        cout<<p -> data<<" ";
        p = p -> next;
    }
    cout<<endl;
}
int main()
{
    int x = 3;
    int y;
    list L;
    node* s = NULL;
    L.create_R();
    cout<<"链表的元素为:\n";
    L.PrintList();
    cout<<"取出第3号元素,并将其值存入y,y = ";
    L.get_element(x,y);
    cout<<y<<endl;
    cout<<"链表长度为:";
    cout<<L.length()<<endl;
    cout<<"元素x所在的指针地址为:";
    cout<<L.locate(x);
    return 0;
}

运行结果如下图所示:
这里写图片描述

 

posted @ 2016-04-21 15:11  larryking  阅读(346)  评论(0编辑  收藏  举报