總結一下鏈表的一些基本操作:
#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[N];
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