单向链表(C++实现)

一 、单向链表:

           单向链表是一种特殊的数组,它的每个元素称为节点,每个节点包括两个部分:数据域(存放数据)、指针域(存放下一个节点的地址)

  • 单向链表的结构:

      

  • 特点:

          链表比数组多了指针域,链表通过上一节点的指针域找下一个数据,如上图所示,它的存储空间不一定连续。

  • 实现:

       //----------------单向链表存储结构-------------------

typedef struct LNode
{
   ElemType     data;   //Data是一个变量,存放结点中的数据
   struct LNode *next;  //*next是指针域,指向结点的下一个结点
}LNode,*LinkList;

       假设L是LinkList型的变量,则L为单链表的头指针,它指向表中第一个节点,若L为空,则所表示的线性表为空表,其长度为0.也可以在单链表中的第一个节点之前附设一个节点,称之为头结点。头结点的数据域可以不存储任何信息,也可以存储线性表的长度等等此类的信息。头结点的指针域存储指向第一个节点的指针(即第一个元素结点的存储位置)。

在单链表中,任何两个的存储位置之间没有固定的联系。然而每个元素的存储位置都包含在其直接前驱节点的信息之中。假设p是指向线性表中第i个数据元素(节点ai)的指针,则p -> next是指向第 i+1 个数据元素(节点ai+1)的指针。即:p -> data=ai;则p -> next -> data = ai+1。

GetElem函数:

Status GetElem(LinkList L,ElemType &e)
{
   p = L->next;         //L为带头结点的单链表的头指针
   j = 1;
   while(p && j < i)    //当第i个元素存在时,将其值赋给e并返回OK,否则返回ERROR
   {                   
      p = p->next;
      ++j;
   }
   if(!p || j > i)    
   {
      return ERROR;
   }
   e = p->data;
   return OK;
}

//--------------------插入----------------------

要插入元素E,首先要生成一个数据域为E的节点,然后插入;插入的过程中要改变指针的指向,只要令E的前驱的指针域指向E然后令E的指针域指向本来E前驱的后继的数据域,这样就插入了一个新元素。即:假设s为指向节点E的指针,s->next = p->next;   p -> next = s;

 在链表中插入结点是时,则需要考虑下面几点情况:
(1) 插入前链表是一个空表,直接插入。
(2) 若插入的是链表第一个节点后,则插入后,该结点为第一个结点。
(3) 若不是第一个结点,则首先要找出该节点的上一个结点,然后按以上插入元素E操作。

代码实现如下:

Status ListInster(Link &L,int i,ElemType e)   //在第i个位置之前插入e
{
   p = L;
   j = 0;
   while(p && j < i - 1)
   {
      p = p -> next;
      ++j;
   }
   if(!p || j > i-1)
   {
     return ERROR;
   }
   s = (LinkList)mallon(sizeof(LNode));    //生成新结点
   s -> data = e;
   s -> next = p->next;
   p->next = s;
   return OK;
}

//-----------------------删除---------------------

与插入思路相同,只是改变节点指向,令要删除的元素的前驱的指针指向要删除元素的后继的数据域。(当然,也要考虑如插入类似的情况)

即: p -> next = p -> next ->next;

代码如下:

Status ListDelete(LinkList &L,ElemType &e)
{
   p = L;
   j = 0;
   while(p -> next && j < i-1)
   {
      p = p->next;
      ++j;
   }
   if(!(p->next) || j > i-1)
   {
     return ERROR;
   }
   q = q->next;
   p -> next =q -> next;
   e = q->next;
   free(q);
   return OK;
}

以下为整体代码:

-----------head.h ---------

#ifndef List

#include<iostream>
using namespace std;

typedef int ElemType;

typedef struct LNode
{
	ElemType     data;
	LNode        *next;
};

class LINK_LIST
{
public:
	LINK_LIST();
	~LINK_LIST();
	bool InitList();
	bool LlistInster(ElemType elem,ElemType pos);
	bool ListDelete(ElemType pos);
	void output(); 
private:
	LNode *head;
};

#endif // !List

---------------fun.cpp---------------

#include"head.h"

LINK_LIST::LINK_LIST()  //初始化
{
	head = new LNode;
	head->next = NULL;
}

LINK_LIST::~LINK_LIST()    //清空链表
{
	LNode *p;
	while (head->next)
	{
		p = head->next;
		head->next = p->next;
		delete p;
	}
}

bool LINK_LIST::InitList()
{
	LNode *p,*temp;
	p = head;
	ElemType num,i = 1;
	cout << "请输入要输入的元素个数:";
	cin >> num;
	cout << "现在输入元素吧!" << endl;
	while (i <= num)
	{
		temp = new LNode;
		cin >> temp->data;
		temp->next = p->next;
		p->next = temp;
		i++;
	}
	return true;
}

bool LINK_LIST::LlistInster(ElemType elem, ElemType pos)
{
	LNode *p,*s;
	ElemType n;
	n = 0;
	p = head;
	while (p && n < pos - 1)
	{
		p = p->next;
		++n;
	}
	if (!p || n > pos - 1)
	{
		return false;
	}
	s = new LNode;
	s->data = elem;
	s->next = p->next;
	p->next = s;
	return true;
}

bool LINK_LIST::ListDelete(ElemType pos)
{
	LNode *p,*q;
	p = head;
	int n = 0;
	while (p && n < pos - 1)
	{
		p = p->next;
		++n;
	}
	if (!p || n > pos - 1)
	{
		return false;
	}
	p->next = p->next->next;
	return true;
}

void LINK_LIST::output()
{
	LNode *p;
	p = head->next;
	while (p != NULL)
	{
		cout << p->data<<" ";
		p = p->next;
	}
	cout << endl;
}

-----------------main.cpp-------------------

#include"head.h"

int main()
{
	LINK_LIST list;
	ElemType type,pos;
	list.InitList();
	list.output();
	cout << "请输入要插入的元素以及位置:";
	cin >> type >> pos;
	list.LlistInster(type,pos);
	list.output();

	cout << "请输入删除元素位置:";
	cin >> pos;
	list.ListDelete(pos);
	list.output();

	system("pause");
	return 0;
}

前半部分部分采用C语言是为了便于理解,后部整体代码为C++就很容易理解了。 

以上代码测试环境为VS2017

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值