数据结构-线性表之单链表(头插法和尾插法)【下】

有兴趣利用链表写贪吃蛇的看这篇https://blog.csdn.net/viafcccy/article/details/84483828

数据结构-线性表之单链表(头插法和尾插法)【上】在这里https://blog.csdn.net/viafcccy/article/details/85041942

链表也是线性表的一种,与顺序表不同的是,它在内存中不是连续存放的。在C语言中,链表是通过指针相关实现的。而单链表是链表的其中一种,关于单链表就是其节点中有数据域和只有一个指向下个节点的指针域。 
创建单链表的方法有两种,分别是头插法和尾插法。

所谓头插法,就是按节点的逆序方法逐渐将结点插入到链表的头部。反之尾插法就是按节点的顺序逐渐将节点插入到链表的尾部。

相对来说,头插法要比尾插法算法简单,但是最后产生的链表是逆序的,即第一个输入的节点实际是链表的最后一个节点。但是在实际情况下常常选用不同的建立方式。

而为了习惯,通常用尾插法来创建链表。这篇文章主要以尾插法为例,但是将头插法的源码放在最后,看完头插法后自己很好理解。

struct Snake
{
	int x;
	int y;
    struct Snake *next;
};

定义两个指针 (snake一直相当于int void这种的数据类型)

snake *tail;
snake *head;

 

tail = (snake*)malloc(sizeof(snake));

给tail指针指向的这个结构体赋值 因为其中的next指针域不知道指向哪里先将它指向NULL(类似于void类型的指针我们不知道它下面会指向哪里) 

  tail ->x=30;
  tail ->y=10;
  tail ->next=NULL;

再以head指针开辟一个snake形式的内存 

head=(snake*)malloc(sizeof(snake));

将head指向的这个结构体中的next指针赋予tail指针

 

head->next=tail;

将尾指针赋予下一个头指针的值 

tail=head;

 然后我们将以上代码写入for循环

void initSnake()
{
  snake *tail;
  snake *head;
  tail = (snake*)malloc(sizeof(snake));
  tail ->x=30;
  tail ->y=10;
  tail ->next=NULL;
  for(i = 0;i<4;i++)
  {
    head=(snake*)malloc(sizeof(snake));
	head->next=tail;
	tail=head;
  }
}

继续以head开辟一个新的snake类型的结构体

此时是不是2中的next已经指向1,tail指向2,head指向了3

于是也就完成了1.2的链接,1.2形成一个链表

只需要继续循环便可开辟内存并且链接起来形成链表

这样就可以将很多分散但是结构相同的结构体关联起来

下面是头插法的源码

// 头插法
int Insert_Last (Node* h, LinkData data)
{
    // 判断数据传入是否正确
    if (NULL == h)
    {
        return FALSE;
    }
     // 创建新结点并判断创建是否成功
    Node* node = (Node*) malloc(sizeof(Node) / sizeof(char));
    if (NULL == node)
    {
        return FALSE;
    }

    // 给结点成员变量赋值
    node->data = data;
    node->next = h->next;   // 和头指针的不同:node->next = *h;

    // 让新结点变为链表的第一个节点
    h->next = node;

    return TRUE;
}

最后cpp模板实现链表

template <class T>           //template:模板,样板
class cNode                          //节点
{
public:                          
	T data;
    cNode *next;
};

template <class T>
class tList                       
{
public:                               //定义成员函数
	tList();
	void Create();                      //创建链表
	bool Empty() const;                 //判断链表是否为空
	void Insert(const T e);         //从尾部插入一个元素
	cNode<T>* GetcNode(int i);             //返回第i个节点
	bool Find(const T e);               //在链表中查找某个值
	~tList();                            //销毁链表,析构
    cNode<T> *head;                        //头节点
};

template <class T>
tList<T>::tList()                 //类的成员函数的实现
{
	head=new cNode<T>;
	head->next=NULL;
}

template <class T>
void tList<T>::Create()
{
    cNode<T> *p;
	p=head;
	p->next=NULL;
}
template <class T>
bool tList<T>::Empty()   const 
{
	return (head->next==NULL);
}

template <class T>
void tList<T>::Insert(const T e)     //insert:插入
{
    cNode<T> *p,*q;
	p=head;
	q=new cNode<T>;
	q->data=e;
	while(p->next)
	{
		p=p->next;
	}
	p->next=q;
	q->next=NULL;
}

template <class T>
cNode<T>* tList<T>::GetcNode(int i)              //返回第i个节点
{
	int k=0;
    cNode<T> *p;
	p=head;
	while(p && k<i)
	{
		p=p->next;
		++k;
	}
	return p;
}


template <class T>
bool tList<T>::Find(const T e)             //在链表中查找某个值
{
	bool flag=false;
    cNode<T> *p;
	p=head->next;
	while(p)
	{
      if(p->data==e)
		{
			flag=true;
			break;
		}
		p=p->next;
	}
	return flag;
}

template <class T>
tList<T>::~tList()
{
	cNode<T> *p;
	while(head)
	{
		p=head->next;
		delete head;
		head=p;
	}
}

 

  • 18
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值