链表的定义及其基本运算
由于链表的描述比较复杂,故此处仅贴出代码,并附上本人遇到的部分问题,以供学习参考之用。
#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;
}
运行结果如下图所示: