单链表比较简单,中间倒也没出什么大问题,只是 在写 插入 和 删除的 算法的 时候 ,时间复杂度 是正常 算法的2倍。后来 改正了。
下面奉上代码。如有 bug,欢迎指出。
// SingleList.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <cstdlib>
enum E_State
{
E_State_Error = 0,
E_State_OK = 1,
};
typedef int ElementType;
struct singleList
{
ElementType data;
singleList * next;
};
E_State initList(singleList & list){
list.next = NULL;
return E_State_OK;
}
E_State destoryList(singleList & list){
singleList * p = list.next;
while (p)
{
singleList * next = p->next;
free(p);
p = next;
}
list.next = NULL;
return E_State_OK;
}
E_State clearList(singleList & l){
return destoryList(l);
}
bool isEmptyList(singleList l){
return l.next == NULL ? true : false;
}
int listLen(singleList l){
singleList * nextList = l.next;
int len = 0;
while (nextList)
{
nextList = nextList->next;
len ++;
}
return len;
}
E_State getElement(singleList list,int index,singleList & element){
singleList * listNext = list.next;
int times = 1;
for (; times < index && listNext; times ++,listNext = listNext->next);
if (times > index || !listNext)
{
return E_State_Error;
}
element = *listNext;
return E_State_OK;
}
singleList * locateElem(singleList l,ElementType e){
singleList * next = l.next;
while (next)
{
if (next ->data == e)
{
return next;
}
next = next->next;
}
return NULL;
}
//单链表 查找前驱 比 双向链表 费劲些。
singleList * preElement(singleList l,ElementType e){
singleList * headList = l.next;//头指针
singleList * nextList = headList;
singleList * lastList = headList;
while (nextList)
{
if (nextList->data == e && nextList != headList)// 头指针没有前驱
{
return lastList;
}
lastList = nextList;
nextList = nextList->next;
}
return NULL;
}
singleList * nextElement(singleList l, ElementType e){
singleList * pLocate = locateElem(l,e);
return pLocate ? pLocate->next:NULL;
}
//后来根据书上代码写的
//插入操作 只要其 前驱不为空即可,可以 从 空表 插入,也可以从 表的尾部的后面插入.
E_State listInsert(singleList & l,int index,ElementType e){
singleList * p = &l;
int times = 0;
//查找插入位置的前驱。。。
for (; p && times < index - 1; times++,p=p->next) ;
if (!p || times > index)// times > index 是为了 防止 times 小于 1 的情况..
{
return E_State_Error;
}
singleList * newNode = (singleList *)malloc(sizeof(singleList));
newNode->data = e;
newNode->next = p->next;
p->next = newNode;
return E_State_OK;
}
//删除只可删除存在的节点。.
E_State listDelete(singleList & l,int index){
singleList * next = l.next;
singleList * last = &l;
int times = 1;
for (;times < index && next;)
{
last = next;
next = next->next;
times ++;
}
if (!next && times > index)
{
return E_State_Error;
}
last->next = next->next;
//释放 从链表中删除的节点...
free(next);
return E_State_OK;
}
/*第一个版本 写的 算法没问题,但是算法复杂度是正常算法的2倍.
E_State listInsert(singleList &l,int index ,ElementType e){
singleList * next = l.next;
singleList * last = &l;
int len = listLen(l);
if (index < 1 || index > len + 1)
{
return E_State_Error;
}
int times = 1;
for (; times < index && next ; times ++,last = next,next = next->next );
singleList * pNewNode = (singleList *)malloc(sizeof(singleList));
pNewNode->data = e;
last->next = pNewNode;
pNewNode->next = next;
return E_State_OK;
}
E_State listDelete(singleList &l,int index){
int len = listLen(l);
if (index < 1 || index > len)
{
return E_State_Error;
}
singleList * pNext = l.next;
singleList * pLast = &l;//这一点很重要。。。
int times = 1;
for (;pNext && times < index; )
{
pLast = pNext;
pNext = pNext->next;
times ++;
}
pLast->next = pNext->next;
//记得释放从链表 去除的 节点
free(pNext);
return E_State_OK;
}
*/
void listTraverse(singleList l){
singleList * next = l.next;
printf("---------------------------\n");
while (next)
{
printf("%d\n",next->data);
next = next->next;
}
printf("---------------------------\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
singleList list1;
//初始化
initList(list1);
//插入
for (int i = 1; i <= 5; i++)
{
listInsert(list1,i,i);
}
listInsert(list1,3,33);
listInsert(list1,1,11);
listInsert(list1,listLen(list1),99);
listInsert(list1,listLen(list1)+1,100);
listTraverse(list1);
//删除
listDelete(list1,1);
listDelete(list1,5);
listDelete(list1,listLen(list1));
listTraverse(list1);
//查找,前驱,后继
singleList find;
getElement(list1,5,find);
singleList * pPre = preElement(list1,find.data);
singleList * pNext = nextElement(list1,find.data);
printf("----单链表第五个元素的值是:%d\t,前驱:%d,后继:%d",find.data,pPre->data,pNext->data);
//释放内存
destoryList(list1);
return 0;
}
原文:http://blog.csdn.net/fuming0210sc/article/details/43793791