码迷,mamicode.com
首页 > 其他好文 > 详细

单链表

时间:2015-07-08 00:30:33      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:

    基本操作: 创建、查找、删除、插入

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<time.h>
  4 
  5 #define OK 1
  6 #define ERROR 0
  7 #define TRUE 1
  8 #define FALSE 0
  9 #define ElementType int
 10 
 11 typedef int Status;
 12 typedef struct Node{
 13     ElementType Element;
 14     struct Node *Next;
 15 }Node;
 16 typedef struct Node LinkList;
 17 
 18 int InitList(LinkList *L)
 19 {
 20     L = (LinkList*)malloc(sizeof(Node)); //给指针分配空间
 21     if(!(L))
 22     {
 23         return ERROR;
 24     }
 25     L ->Next = NULL; //
 26     return OK;
 27 }
 28 int ListLength(LinkList *head)
 29 {
 30     int length =0;
 31     LinkList *p = head -> Next;
 32     while(p  != NULL)
 33     {
 34         length ++;
 35         p  = p->Next;
 36     }
 37     return length;
 38 }
 39 /*将元素插入到链表的第i个位置*/
 40 int InsertList(ElementType e,int i,LinkList *head)
 41 {
 42     LinkList *p = head ;
 43     LinkList *temp;
 44     if(i <= ListLength(head))
 45     {
 46         while(i-1)
 47         {
 48             p = p->Next;
 49             i--;
 50         }                     //p是第i个结点的前一个结点
 51         temp = (Node*)malloc(sizeof(LinkList));
 52         temp ->Element = e;
 53         temp ->Next = p ->Next;
 54         p -> Next = temp;
 55         return OK;
 56     }
 57     else
 58     {
 59         return ERROR;
 60     }
 61 }
 62 //将列表中的元素输出
 63 void ListTraverse(LinkList *head)
 64 {
 65     LinkList *p = head -> Next;
 66     while(p)
 67     {
 68         printf("%d ",p->Element);
 69         p = p ->Next;
 70     }
 71 }
 72 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
 73 /* 操作结果:删除list的第i个数据元素,并用e返回其值,list的长度减1 */
 74 Status ListDelete(LinkList *head,int i,ElementType *e)
 75 {
 76     LinkList *p = head;
 77     LinkList *temp;
 78     if(i <= ListLength(head))
 79     {
 80         while(i-1)
 81         {
 82             p = p -> Next;
 83             i--;
 84         }   //p指向被删除结点的前一项
 85         temp = p -> Next;
 86         p -> Next = temp ->Next;
 87         free(temp);
 88         return OK;
 89     }
 90     else
 91         return ERROR;
 92 }
 93 /*得到head中第i个元素的值*/
 94 ElementType GetElement(LinkList *head,int i)
 95 {
 96     LinkList *p = head;
 97 //    LinkList *temp;
 98     if(i <= ListLength(head))
 99     {
100         while(i)
101         {
102             p = p -> Next;
103             i--;
104         }   //p指向第i个结点
105 
106         return p ->Element;;
107     }
108     else
109         return ERROR;
110 }
111 
112 /*
113 声明一个结点temp和计数器变量i
114 初始化一空链表L
115 循环
116     初始化temp
117     temp插入到头结点和前一新结点之间
118 ***********************************************************
119 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
120 void CreateListHead(LinkList *L, int n)
121 {
122     LinkList *temp;
123     int i;
124     srand(time(0));
125     L = (LinkList*)malloc(sizeof(Node));
126     for(i = 0;i < n; i++)
127     {
128         temp = (LinkList*)malloc(sizeof(Node));
129         temp -> Element = rand() %100 +1;
130         temp -> Next = L ->Next;
131         L -> Next = temp;
132     }
133 
134 }
135 //尾插法
136 void CreateListTail(LinkList *L,int n)
137 {
138     LinkList *temp,*p;
139     int i;
140 
141     L = (LinkList*)malloc(sizeof(Node));
142     p = L;
143     for(i =0;i < n; i++)
144     {
145         temp = (LinkList*)malloc(sizeof(Node));
146         temp  -> Element = rand()%100 +1;
147         p -> Next= temp;
148         p = temp;
149 
150     }
151     p -> Next = NULL;
152 
153 }
154 /* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
155 Status ClearList(LinkList *L)
156 {
157     LinkList *q,*p;
158     p = L-> Next;
159     while(p  != NULL)
160     {
161         q = p -> Next;
162         free(p);
163         p = q;
164     }
165     L -> Next = NULL;
166     return OK;
167 }
168 /***********************************
169 **************列表反转的3种方法****
170 ***********************************
171 ListReverse1
172 
173 */
174 LinkList* ListReverse1 (LinkList *L)
175 {
176     LinkList *current;
177     LinkList *p;
178 
179     current = L -> Next;
180     while(current -> Next  != NULL)
181     {
182         p = current -> Next;
183         current -> Next = p -> Next ;
184         p -> Next = L ->  Next;
185         L -> Next = p;
186     }
187     return L;
188 }
189 LinkList* LisReverse2(LinkList *L)
190 {
191     LinkList *current ,*pnext,*prev;
192     if(L == NULL || L -> Next == NULL)
193         return L;
194     current = L->Next;
195     pnext = current -> Next;
196     current -> Next = NULL;
197     while(pnext)
198     {
199         prev = pnext -> Next;
200         pnext -> Next = current;
201         current = pnext;
202         pnext = prev;
203     }
204     L -> Next = current;
205     return L;
206 }
207 int HasLoop (LinkList *L)
208 {
209     LinkList *q,*p;
210     int step1 = 0;
211 
212 
213     q = L -> Next;
214     while(q)
215     {
216         step1++;
217         int step2 = 0;
218         p = L -> Next;
219         while(p)
220         {
221             step2++;
222             if(p == q)
223             {
224                 if(step1 == step2)
225                     break;
226                 else
227                     return 1;
228             }
229             p = p -> Next;
230         }
231         q = q -> Next;
232     }
233     return 0;
234 }
235 void CreateLoop(LinkList *L ,int num)
236 {
237     int i;//count
238     LinkList *current;
239     LinkList *p = L -> Next;
240     for(i = 0;i < num; i++)
241     {
242         if(p == NULL)
243         {
244             return 0;
245         }
246         p = p -> Next;
247     }
248     current = p;
249     while(p->Next)
250     {
251         p = p -> Next;
252     }
253     p -> Next = current;
254     return 1;
255 }
256 int main()
257 {
258     LinkList *l;
259     InitList(l);
260     ListLength(l);
261     return 0;
262 }

 

距离-标尺问题

*求单链表的倒数第k个数,声明2个指针,一个指针先走k步,然后两个指针一起走。当第一个指针next == NULL时,di二个指针就是倒数第k个结点的值。

*用标尺法求未知长度单链表的中间节点

**声明2个指针,search,mid。search指针的移动速度是mid指针的2倍,当search指针到达链表结尾时。mid指针到达链表中间。

 

判断链表是否有环

*使用2个快慢指针可以判断。如果有环,它们在某点相遇。

    int HasLoop (LinkList *L)
{
    LinkList *q,*p;
    q =p =L -> Next;
    int stepq//length of q
    int stepp //length of p
    while(p != NULL && q != NULL && q -> Next != NULL)
    {
        p = p -> Next;
        if(q -> Next != NULL)
            q = q -> Next -> Next;
        if(q = p)
            return 1
    }
    return 0;
}      

*第二种方法 和嵌套循环类似 设2个指针q、p,p走一步,q每次从头走到结束。如果有环,结点相同时步数不相等。

int HasLoop (LinkList *L)
{
    LinkList *q,*p;
    int step1 = 0;

q = L -> Next;
    while(q)
    {
        step1++;
        int step2 = 0;
        p = L -> Next;
        while(p)
        {
            step2++;
            if(p == q)
            {
                if(step1 == step2)
                    break;
                else
                    return 1;
            }
            p = p -> Next;
        }
        q = q -> Next;        
    }
    return 0;
}

 

单链表建环

*将最后一个结点与第num个结点连接起来。使用循环遍历到第num个结点,声明current指针用来保存结点。将指针p循环到最后,将p和current连接起来。

void CreateLoop(LinkList *L ,int num)
{
    int i;//count
    LinkList *current;
    LinkList *p = L -> Next;
    for(i = 0;i < num; i++)
    {
        if(p == NULL)
        {
            return 0;
        }
        p = p -> Next;
    }
    current = p;
    while(p->Next)
    {
        p = p -> Next;    
    }
    p -> Next = current;
    return 1;
}

删除链表中重复的元素

*声明指针p从第一个结点循环到最后一个,每次循环时用指针q,从p遍历到最后一个指针。如果有重复的结点 free()掉

 

Thanks> http://www.nowamagic.net/librarys/veda/detail/2241

 

单链表

标签:

原文地址:http://www.cnblogs.com/yangRyoung/p/4628899.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!