一步一步学数据结构之1--1(单链表)

Posted on 2013-08-01 19:58  冰天雪域  阅读(179)  评论(0编辑  收藏  举报

        用一组地址任意的存储单元存放线性表中的数据元素,以元素(数据元素的映象) + 指针(指示后继元素存储位置)= 结点(表示数据元素 或 数据元素的映象),以“结点的序列”表示线性表称作线性链表(单链表)。

       有几个基本概念需要掌握,如下:

             1.表头结点

                    链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息。

             2.数据结点

                    链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息

             3.尾结点

                    链表中的最后一个数据结点,其下一元素指针为空,表示无后继

 

             这里主要介绍线性表的常用操作:

 

                     l 创建线性表

                     l 销毁线性表

                     l 清空线性表

                     l 将表中元素倒置

                     l 表元素插入

                     l 表元素删除

                     l 获取表中某个位置的元素

                     l 获取表长度

 

              

             代码总分为三个文件:

                           LinkList.h : 放置功能函数的声明,以及表的声明,表结点的定义 

                           LinkList.c : 放置功能函数的定义,以及表的定义

                           Main.c      : 主函数,使用功能函数完成各种需求,不过一般用作测试

 

 

            这里着重说下插入操作﹑删除操作和倒置操作:

                    插入操作:

                            如图

                          

                    插入元素方法:

                            首先判断线性表﹑插入位置是否合法

                            由表头开始通过next指针移动pos次后,当前元素的next指针即指向要插入的位置

                            把当前元素(current)的next指针包含的地址赋给新元素(node)的next指针

                            把新元素(node)的地址赋给当前元素(current)的next指针

                            最后把线性表长度加1

                   删除操作:

                          如图

                                    

 

                   删除元素方法:

                          首先判断线性表﹑删除位置是否合法

                          获取第pos个元素

                         将第pos个元素的next指针保存的地址赋给第pos个元素前一个元素的next指针

                         最后把表长度减1

 

                      倒置操作:

                         如图

                            

                倒置元素方法:

                        把头结点指向的首元素的next指针赋为NULL

                        然后把首元素以后的结点依次每个插入到头结点和首元素中间

 

OK! 上代码:

 

LinkList.h

 

#ifndef _LINKLIST_H_
#define _LINKLIST_H_

typedef void LinkList;
typedef struct _tag_LinkListNode LinkListNode;

struct _tag_LinkListNode
{
	LinkListNode* next;
};

LinkList* LinkList_Create();

void LinkList_Destroy(LinkList* list);

void LinkList_Clear(LinkList* list);

void LinkList_Reverse(LinkList* list);

int LinkList_Length(LinkList* list);

int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);

LinkListNode* LinkList_Get(LinkList* list, int pos);

LinkListNode* LinkList_Delete(LinkList* list, int pos);

#endif


 

LInkList.c

 

#include <stdio.h>
#include <malloc.h>
#include "LinkList.h"

typedef struct _tag_LinkList
{
	LinkListNode header;
	int length;
}TLinkList;

LinkList* LinkList_Create()
{
	TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));

	if(ret != NULL)
	{
		ret->length = 0;
		ret->header.next = NULL;
	}

	return ret;
}

void LinkList_Destroy(LinkList* list)
{
	free(list);
}

void LinkList_Clear(LinkList* list)
{
	TLinkList* sList = (TLinkList*)list;

	if(sList!=NULL)
	{
		sList->header.next = NULL;
		sList->length = 0;
	}
}

void LinkList_Reverse(LinkList* list)
{
	TLinkList* sList = (TLinkList*)list;
	
	if((sList!=NULL)&&(sList->length>1))
	{
		LinkListNode* current = (LinkListNode*)sList;
		LinkListNode* p = current->next;
		LinkListNode* q = current->next;
		
		q = q->next;
		p->next = NULL;
		p = q;
		
		while(p != NULL)
		{
			q = q->next;
			p->next = current->next;
			current->next = p;
			p = q;
		}
	}
}

int LinkList_Length(LinkList* list)
{
	TLinkList* sList = (TLinkList*)list;

	int ret = -1;

	if(sList!=NULL)
	{
		ret = sList->length;
	}

	return ret;
}

int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
	TLinkList* sList = (TLinkList*)list;

	int ret = (sList!=NULL) && (pos>=0) && (node!=NULL);
	
	int i = 0;

	if(ret)
	{
		if(pos >= sList->length)
		{
			pos = sList->length;
		}

		LinkListNode* current = (LinkListNode*)sList;

		for(i=0; (i<pos)&&(current->next!=NULL); i++)
		{
			current = current->next;
		}

		node->next = current->next;

		current->next = node;

		sList->length++;
	}

	return ret;
}

LinkListNode* LinkList_Get(LinkList* list, int pos)
{
	TLinkList* sList = (TLinkList*)list;

	LinkListNode* ret =NULL;

	int i = 0;

	if((sList!=NULL)&&(pos>=0) && (pos<sList->length))
	{
		LinkListNode* current = (LinkListNode*)sList;

		for(i=0; (i<pos)&&(current->next!=NULL); i++)
		{
			current = current->next;
		}

		ret = current->next;
	}

	return ret;
}

LinkListNode* LinkList_Delete(LinkList* list, int pos)
{
	TLinkList* sList = (TLinkList*)list;

	LinkListNode* ret = NULL;

	int i = 0;

	if((sList!=NULL)&&(pos>=0)&&(pos<sList->length))
	{
		LinkListNode* current = (LinkListNode*)sList;

		for(i=0; i<pos; i++)
		{
			current = current->next;
		}

		ret = current->next;

		current->next = ret->next;

		sList->length--;
	}

	return ret;
}


main.c

 

#include <stdio.h>
#include <stdlib.h>
#include "LinkList.h"

typedef struct _tag_Value
{
	LinkListNode header;
	int v;
}Value;

int main(void)
{
	LinkList* list = LinkList_Create();

	int i = 0;

	Value v1, v2, v3, v4, v5;

	v1.v=1, v2.v=2, v3.v=3, v4.v=4, v5.v=5;

	LinkList_Insert(list, (LinkListNode*)&v1, 0);
	LinkList_Insert(list, (LinkListNode*)&v2, 0);
	LinkList_Insert(list, (LinkListNode*)&v3, 0);
	LinkList_Insert(list, (LinkListNode*)&v4, 0);
	LinkList_Insert(list, (LinkListNode*)&v5, 0);

	Value* pV = NULL;

	for(i=0; i<LinkList_Length(list); i++)
	{
		pV = (Value*)LinkList_Get(list, i);

		printf("%d\n", pV->v);
	}

	while(LinkList_Length(list) > 0)
	{
		pV = (Value*)LinkList_Delete(list, LinkList_Length(list)-1);

		printf("%d\n", pV->v);
	}

	LinkList_Destroy(list);

	return 0;
}


 

 

Copyright © 2024 冰天雪域
Powered by .NET 8.0 on Kubernetes