链表:是一种递归的数据结构,它或者为空(NULL),或者是指向一个结点(node)的引用(指针),该结点含有一个泛型的元素和一个指向另一条链表的引用(指针)。
为方便,以下泛型均用int型数据代替。
一.链表与数组的差异
数组:①长度必须是明确的 ②数组元素的地址必须是连续的 ③在数组中任意位置插入一个数是很困难的
链表:①长度可以是未知的 ②内部结点与结点的地址不需要连续 ③可以很方便的插入 删除 替换等操作
二.代码实现
声明Node结点类,作为基本数据类型
class Node
{
public: //注意要声明为public 之后要改变node值的
int val; //当前结点的值
Node * next; //指向当前node的下一个结点
Node() //定义无参构造进行初始化
{
val=0;
next=NULL;
}
};
声明LinkList类,函数不全,实现了几个主要函数,日后再补
class LinkList
{
public:
Node *head;
public:
LinkList() {head=NULL;}
~LinkList(); //清空LinkList
void insertionNodeInHead(Node *newhead); //在链表头部插入一个新结点
void deleteNodeInHead(); //删除一个结点
void insertionNodeInEnd(Node *newlast); //在结尾插入新结点
void ergodic(); //遍历当前链表
void insertionNodeAfterVal(Node *newNode,int val); //在值为val的结点后插入新结点
void deleteNodeEqualVal(int val); //删除值为val的结点
};
各个函数的实现
LinkList::~LinkList()
{
Node *p=head;
while(head!=NULL)
{
p=head;
head=head->next;
delete p;
}
}
void LinkList::insertionNodeInHead(Node *newhead)
{
Node * oldhead=head; //保存下旧的链表头
head=new Node(); //new一个新的链表头
head->val=newhead->val; //为新链表头赋值
head->next=oldhead; //将新链表头连到旧链表头的前面
}
void LinkList::ergodic()
{
Node *curr=head; //取当前结点为头结点
while(curr!=NULL) //当前结点不为空,即不是最后一个结点时
{
cout<<curr->val<<" ";
curr=curr->next;
}
cout<<endl;
}
void LinkList::deleteNodeInHead()
{
Node *p=head->next;
delete head; //防止内存泄漏 书中没有 是因为java自动释放
head=p;
}
void LinkList::insertionNodeInEnd(Node *newlast)
{
Node *p=head;
while(p->next!=NULL) //注意不能让p为NULL,不然后面访问p会访问野指针,程序崩溃
{
p=p->next;
}
p->next=newlast;
}
void LinkList::insertionNodeAfterVal(Node *newNode,int val)
{
Node *p=head;
while(p!=NULL&&p->val!=val)
{
p=p->next;
}
if(p==NULL) cout<<"false"<<endl;
else
{
Node *pnext=p->next;
p->next=newNode;
newNode->next=pnext;
}
}
void LinkList::deleteNodeEqualVal(int val)
{
Node *p=head;
Node *q=new Node();
while(p->next!=NULL&&p->val!=val)
{
q=p;
p=p->next;
}
if(p->next==NULL&&p->val==val)
{
q->next=NULL;
delete p;
}
else
{
q->next=p->next;
delete p;
}
}
测试样例
int main()
{
LinkList linkList;
Node *cur=NULL;
for(int i=1;i<10;i++) //创建一系列结点
{
cur=new Node();
cur->val=i;
cur->next=linkList.head;
linkList.head=cur;
}
linkList.ergodic(); //9 8 7 6 5 4 3 2 1
Node *newhead=new Node();
newhead->val=10;
newhead->next=linkList.head;
linkList.insertionNodeInHead(newhead);
linkList.ergodic(); //10 9 8 7 6 5 4 3 2 1
linkList.deleteNodeInHead();
Node *newlast=new Node();
newlast->val=100;
newhead->next=NULL;
linkList.insertionNodeInEnd(newlast);
linkList.ergodic(); //=>9 8 7 6 5 4 3 2 1 100
Node *nodeAfterVal=new Node();
nodeAfterVal->val=101;
nodeAfterVal->next=NULL;
linkList.insertionNodeAfterVal(nodeAfterVal,1);
linkList.ergodic(); //=>9 8 7 6 5 4 3 2 1 101 100
linkList.deleteNodeEqualVal(101); //9 8 7 6 5 4 3 2 1 100
linkList.ergodic();
linkList.deleteNodeEqualVal(100); //9 8 7 6 5 4 3 2 1
linkList.ergodic();
cout<<"hello world"<<endl;
return 0;
}