您的位置:首页 > 其它

链表的基本操作

2015-04-23 21:05 127 查看
总结一下链表的一些基本操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 12
#define M 20
typedef int elemType;

//定义单链表节点类型
typedef struct Node
{
elemType element;
Node *next;
}Node;

//初始化线性表,即置单链表的表头指针为空
void initList(Node **pNode)
{
*pNode = (Node *) malloc(sizeof(Node));
(*pNode) ->next = NULL;
printf("initList 函数执行,初始化成功\n");

}

//创建线性表,此函数输入负数终止读取数据
Node *creatList(Node *pHead)
{
Node *p1;
Node *p2 = NULL;
p1= (Node *)malloc(sizeof(Node)); //申请新节点
if (p1 == NULL || p2 == NULL)
{
printf("内存分配失败\n");
exit (0);
}
memset(p1, 0, sizeof (Node));

scanf("%d", &p1->element); //输入新节点
p1->next = NULL;  //新节点的指针置空。
while(p1->element > 0)
{
if(pHead == NULL)  //空表,接入表头
pHead = p1;
else
p2->next = p1;  //非空表,接入表尾
p2 = p1;
p1 = (Node *) malloc (sizeof (Node)); //在重新申请一个节点
if (p1 == NULL || p2 == NULL)
{
printf("内存分配失败\n");
exit (0);
}
memset(p1, 0, sizeof(Node));
scanf("%d",&p1->element);
p1->next = NULL;

}
printf("creatLise函数执行,链表创建成功\n");
return pHead;
}

//打印链表,链表的遍历
void printList (Node *pHead)
{
if(pHead == NULL)
printf("PrintList 函数执行,链表为空");
else
{
while (NULL != pHead)
{
printf("%5d",pHead->element );
pHead = pHead->next;
}
printf("\n");

}
}

//清除线性表L中的所以元素,即释放单链表L中
//的所有节点,使之成为一个空表
void clearList(Node *pHead)
{
Node* pNext; //定义一个与pHead相邻节点

if (pHead == NULL)
{
printf("clearList函数执行,链表为空\n");
return;
}
while(pHead->next != NULL)
{
pNext = pHead -> next; //保存下一节点的指针
free(pHead);
pHead = pNext;  //表头下移
}
printf("clesrList 函数执行,链表已经清除\n");
}

//返回单链表的长度
int sizeList(Node *pHead)
{
int size = 0;
while(pHead != NULL)
{
size ++;  //遍历链表大小实际比实际链表小1
pHead = pHead->next;
}
printf("sizeList函数执行,链表长度:%d\n",size );
return size;
}

//检测链表是否为空,若空则返回1,否则返回0
int isEmptyList(Node*pHead)
{
if(pHead == NULL)
{
printf("isEmptyList函数执行,链表为空\n");
return 1;
}
printf("isEmptyList函数执行,链表为空\n");
return 0;
}

//返回单链表中第pos个节点的元素,若pos超出范围,则停止程序运行
elemType getElemnt(Node *pHead, int pos)
{
int i = 0;
if(pos < i)
{
printf("pos值非法\n");
return 0;
}
if (pHead == NULL)
{
printf("getElement函数执行,链表为空\n");
return 0;
//exit (1);  //退出程序
}
while(pHead != NULL)
{
++i;
if(i == pos)
break;
pHead = pHead->next; //转移到下一个节点
}
if (i < pos)
{
printf("getElement函数执行,pos值超出链表长度\n");
return 0;
}
return (pHead->element);

}

//从单链表中查找链表具有给定值X的第一个元素,
//若查找成功则返回该节点data域的存储地址,否则返回NULL。
elemType *getElementAddr(Node * pHead, elemType x)
{
if (pHead == NULL)
{
printf("getElementAddr函数执行,链表为空\n");
return NULL;
}
if (x < 0)
{
printf("getElementAddr函数执行,给定的x值不合法\n");
return NULL;
}
//判断是否到链表末尾,以及是否存在所要查找的元素
while((pHead->element != x ) && (pHead->next != NULL))
{
pHead = pHead->next;
}
if (pHead->element == x)
//printf("gerElementAddr函数执行,元素%d的地址为: 0x%x\n",x,&(pHead->element));
return &(pHead->element);
}

//把单链表中第pos个节点的元素替换为x,若修改成功返回1,否则返回0
int modifyElem(Node *pNode, int pos, elemType x)
{
Node *pHead;
pHead = pNode;
int i = 0 ;
if (pHead == NULL)
{
printf("modifyElem函数执行,链表为空\n");
return 0;
}
if(pos < 1)
{
printf("modifyElem函数执行,pos值非法\n");
return 0;
}
while(pHead != NULL)
{
++i;
if (pos == i)
break;
pHead = pHead->next;
}
if (i < pos)
{
printf("modifyElem函数执行,pos值超出链表长度\n");
return 0;
}
pNode = pHead->next;
pNode->element = x;
//printf("modeifyElemAddr函数执行\n");
return 1;
}

//向单链表的表头插入一个元素
int insertHeadList(Node **pNode,elemType insertElem)
{
Node *pInsert;
pInsert = (Node *) malloc (sizeof (Node));
memset(pInsert,0,sizeof(Node));
pInsert->element = insertElem;
pInsert->next = *pNode;
*pNode = pInsert;
printf("insertHeadLise函数执行,向表头插入元素成功\n");
return 1;
}

//向单链表末尾添加一个元素
int insertLastList (Node **pNode, elemType insertElem)
{
Node *pInsert;
Node *pHead;
Node *ptemp; //定义一个临时链表来存放第一个节点。

pHead = *pNode;
ptemp = pHead;
pInsert = (Node *)malloc(sizeof(Node));
memset(pInsert, 0 ,sizeof(Node));
pInsert->element = insertElem;

while(pHead->next != NULL)
{
pHead= pHead->next; //找到表末尾
}
pHead->next = pInsert;
*pNode = ptemp;
printf("insertLastLisr函数执行成功,想链表末尾插入元素成功\n");
return 1;
}

//向有序单链表中插入元素,不改变链表的有序性
int insertOrderList(Node **pNode, elemType insertElem)
{
Node *pHead, *ptemp = NULL, *pInsert;
pHead = *pNode;
pInsert = (Node *)malloc(sizeof(Node)); //申请一个新的节点
if(pInsert == NULL)
{
printf("内存分配失败,结束程序\n");
exit(1);
}
pInsert->element = insertElem;

//把新节点插入到表头中
if (pHead == NULL || insertElem < pHead->element)
{
pInsert->next = pHead;
*pNode = pInsert;
return 1;
}
//顺序查找,找出insertElem的插入位置
while(pHead != NULL)
{
if (insertElem < pHead->element)
break;
else
{
ptemp = pHead;
pHead = pHead->next;
}

}

//把x节点插入到ptemp与pHead之间
pInsert->next = pHead;
ptemp->next = pInsert;

return 1;

}

//从单链表中删除表头节点,并把该节点
//的值返回,若删除失败则停止程序运行
elemType deleteFirstList(Node *pHead)
{
elemType temp;
Node *pNode;
pNode = pHead; //暂存表头节点指针,以便回收
if (pHead == NULL)
{
printf("单链表为空,退出程序\n");
exit (1);
}
pHead = pHead->next; //使表头指针指向第二个节点
temp = pNode->element; //暂存原表头元素,以便返回
free(pNode);  //回收被删除的表头数据
return temp; //返回第一个节点的值
}

//从单链表中删除结尾节点并返回它的值,若删除失败则停止程序运行
elemType deleteLastList( Node *pHead)
{
Node *pNode, *ptemp = NULL;
elemType lastelement;
pNode = pHead; //指向表头节点
if (pHead == NULL)
{
printf("链表为空,退出程序\n");
exit (1);
}

while (pNode ->next != NULL)
{
ptemp = pNode;
pNode = pNode->next;  //查找链表末尾
}

//若单链表中只有一个节点,则只需要修改表头指针
if (ptemp == NULL)
pHead = pHead->next;
//删除表尾节点
else
ptemp->next = NULL;
//暂存表尾元素,以便返回
lastelement = pNode->element;
free(pNode);
return lastelement;  //返回表尾元素值
}

//从单链表中删除第pos个节点,并返回它的值,若删除失败接受程序运行
elemType deletePosList (Node *pHead, int pos)
{
int i = 0;
Node *pNode, *ptemp = NULL;
pNode = pHead;
elemType poselement;
if (pNode == NULL || pos <= 0)
{
printf("单链表为空或者pos值非法\n");
exit (1);
}

/*从单链表中找到第pos个节点*/
while(pNode != NULL)
{
i++;
if(i = pos)
break;
ptemp = pNode;
pNode = pNode->next;

}

if(pNode == NULL)
{
printf("pos值非法,退出程序\n"); //链表中不存在第pos个节点
exit(1);
}
//pos =1,删除表头节点
if (pos == 1)
pHead = pHead->next;
/* 否则删除非表头结点,此时cp指向该结点,ap指向前驱结点 */
else
ptemp->next = pNode->next;

poselement = pNode->element;
free(pNode);
return poselement;

}

//找到第index个元素,返回节点
Node * findnode( Node *phead, int index)
{
if(!phead) return NULL;
Node * pnode = phead;
while (index --)
{
pnode = pnode->next;
if (!pnode)
return NULL;

}
return pnode;
}

//找到前驱节点
Node * find_preNode(Node *phead, Node *pnode)
{
if(!pnode) return NULL;
Node *preNode = phead;
while (preNode)
{
if(preNode->next == pnode)
return preNode;
preNode = preNode->next;
}
return NULL;
}

//交换链表中的两个元素
void swipList(Node **pHead, int i, int j)
{
if(!pHead) return;
//找出节点
Node *pnode1 = findnode(*pHead, i);
Node *pnode2 = findnode(*pHead,j);
//找出前驱节点
Node *pre1 = find_preNode(*pHead, pnode1);
Node *pre2 = find_preNode(*pHead, pnode2);

//相邻的情况
Node *pBefore = NULL, *pAfter = NULL, *pPre = NULL;
if (pre2 == pnode1)
{
pBefore = pnode1;
pAfter = pnode2;
pPre = pre1;
}
if (pre1 == pnode2)
{
pBefore = pnode2;
pAfter = pnode1;
pPre = pre2;
}
if (pre2 == pnode1 ||pre1 == pnode2)
{
pPre->next = pAfter;
pBefore->next = pAfter ->next;
pAfter->next = pBefore;
}
else
{
//不相邻的情况
Node *pnext1 = pnode1 ->next;
Node *pnext2 = pnode2->next;
pnode1->next = pnode2->next;
pre1->next = pnode2;
pre2->next = pnode1;
pnode2->next = pnext1;
}

}

//链表的排序
void fastsort(Node **phead, Node *end)
{
Node *right;
Node **left_walk, **right_walk;
Node *pivot, *old;
int count, left_count, riht_count;
if(*phead == end)
return;
do
{
pivot = *phead;
left_walk = phead;
right_walk = &right;
left_count = riht_count = 0;
//取第一个节点作为比较的基准点,小于基准点的在左面的子链表中,
//大于基准的在右边的子链表中
for (old = (*phead)->next; old != end; old = old ->next)
{
if (old->element < pivot->element)
{
//小于基准,加入到左边的子链表,继续比较
++ left_count;
*left_walk = old; //把该节点加入到左边的链表中
left_walk = &(old->next);

}
else   //大于基准,加入到右边的子链表,继续比较
{
++riht_count;
*right_walk = old;
right_walk = &( old->next);

}
}

//合并链表
*right_walk = end; //结束右链表
*left_walk = pivot; //把基准链表置于正确位置
pivot->next = right; //链表合并

//对较小的子链表进行快速排序,较大的子链表进行迭代排序
if (left_walk > right_walk)
{
fastsort( &(pivot->next), end);
end = pivot;
count = left_count;
}
else
{
fastsort(phead, pivot);
phead = &(pivot ->next);
count = riht_count;
}

} while (count >1 );

}

int main()
{
int a
;
int i;
Node *p , *h , *s;

initList(&h);
p = h;

srand(time(NULL));
//产生随机数组
for ( i =0; i < N; i++)
{
a[i]=rand() % M + 1;
}
printf("随机数序列为:\n");
for (int i = 0; i < N; i++)
{
printf("%5d",a[i]);
//insertLastList( h, a[i]);
}
printf("\n");

//利用数组初始化链表
for (int i = 0; i < N; i++)
{
s = (Node *)malloc(sizeof(Node));  //申请一个新节点
memset(s, 0, sizeof(Node));
s->element = a[i];
p->next = s;
p = s;
}
p->next = NULL;

Node * head = h->next;

int pos = 11;
int k = getElemnt(head,pos);
printf("第%d个元素为:%d\n",pos,k);

printf("链表:\n");
printList(head); //打印链表

modifyElem(head, 2, 8);
printf("将位置3元素替换成8之后的链表:\n");
printList(head); //打印链表

swipList( &head, 2, 4);
printf("交换3,5位置之后的链表:\n");//因为传进去的是不带表头的数据
printList(head); //打印链表

//FastSort(&head, 1, sizeList(head) - 1);

fastsort(&head,p->next);

printf("快速排序:\n");
printList(head);

clearList(h);

system("pause");
return 0;
}




参考于:http://blog.csdn.net/liuduoqing/article/details/2278492

http://www.jb51.net/article/37300.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: