数据结构-线性链表

来源:互联网 发布:绣花制版软件 编辑:程序博客网 时间:2024/05/17 07:34

步入链表啦,链表在查找方面实在麻烦,需要一次次遍历,不过它在插入和删除方面却很从容,只需要改变它的指针域就可实现,和顺序表各有千秋。

1、代码中L始终代表头结点,所以代码中都用其他变量来替代它移动,保证头结点有人保护
2、p->next及p->next->next的遍历的终结位置要注意

看到了个快慢指针的问题,就是在不知链表长度的情况下最快找到中间节点
1、通过遍历整个链表获得长度,在通过长度找到中间结点
2、设置两个指针,一个每次移动两位,一个移动一位
快慢指针应用于:判断单链表是否为循环链表,在有序链表中寻找中位数
http://www.cnblogs.com/hxsyl/p/4395794.html

/**    *快慢指针**/Status FastAndSlowPt(LinkList L, ElemType *e){    LinkList p,s;    p = L;    s = L;    while(p->next != NULL)    {        if(p->next->next != NULL)        {            p = p->next->next;            s = s->next;        }        else        {            p = p->next;            s = s->next;        }    }    *e = s->data;    return OK;}
#include "stdio.h"#include "stdlib.h"#include "math.h"#define MAXSIZE 20#define OK 1#define ERROR 0typedef int Status;typedef int ElemType;typedef struct Node{    ElemType data;    struct Node *next;}Node;typedef struct Node *LinkList; //定义链表//输出数据Status visit(ElemType e){    printf("%d ", e);    return;}//输出整个链表Status ListTraverse(LinkList L){    LinkList p;    //切勿写成p=L,这是将p赋值为头结点,而数据从头结点后一个结点开始    p = L->next;    while(p)    {        visit(p->data);        p = p->next;    }    return OK;}/**    *初始化链表**/Status ListInit(LinkList *L){    *L = (LinkList)malloc(sizeof(Node)); //生成头结点    if(!(*L))   //未分配空间        return ERROR;    (*L)->next = NULL; //建立头结点    return OK;}/**    *链表插入第i个位置数据操作**/Status ListInsert(LinkList *L, int i, ElemType e){    int k = 1;    LinkList p,s;    p = *L;    while(p && k<i) //遍历到i-1    {        p = p->next;        k ++;    }    if(!p || k>i)//结点i不存在        return ERROR;    s = (LinkList)malloc(sizeof(Node));//生成新节点,存储e数据    s->data = e;    //一下两句不能颠倒否则会使链表断裂,就是s->next = s;    s->next = p->next;    p->next = s;    return OK;}/**    *链表删除第i个位置数据操作**/Status ListDelete(LinkList *L, int i, ElemType *e){    int k=1;    LinkList p,s;    p = *L;    while(p->next && k<i)    {        p = p->next;        k++;    }    if(!p || k>i)        return ERROR;    s = p->next;    p->next = p->next->next;//    p->next = s->next;    *e = s->data;//将第i位置的数据赋值给*e    free(s);    return OK;}/**    *头插法生成链表**/Status ListCreHead(LinkList *L, int i){    LinkList p;    int k;    *L = (LinkList)malloc(sizeof(Node));    (*L)->next = NULL;//同链表初始化操作,建立头结点    for(k=0; k<i; k++)    {        p = (LinkList)malloc(sizeof(Node));        p->data = k+1;        //同插入结点操作        p->next = (*L)->next;        (*L)->next = p;    }    return OK;}/**    *尾插法生成链表**/Status ListCreTail(LinkList *L, int i){    LinkList p,r;    int k;    *L = (LinkList)malloc(sizeof(Node));    (*L)->next = NULL;//*L要始终指向头结点,作为链表的标志,所以不能移步外地    r = *L;//r替代L作为移动指针    for(k=0; k<i; k++)    {        p=(LinkList)malloc(sizeof(Node));        p->data = k+1;        r->next = p;        r = p;    }    p->next = NULL;    return OK;}/**    *整表删除**/Status ListAllDelete(LinkList *L){    LinkList p, q;    p = (*L)->next;    /**        *从头结点开始删除,若从最后一个结点删除,        *需要遍历到最后且没指向前一个结点的指针    **/    while(p)    {        q = p->next;        free(p);        p = q;    }    (*L)->next = NULL;    printf("\n删除完毕!");    return OK;}int main(void){    LinkList L, S;    ElemType e;    ListCreHead(&L, 6);    printf("头插法:");    ListTraverse(L);//    ListCreTail(&S, 6);//    printf("\n尾插法:");//    ListTraverse(S);//    ListAllDelete(&S);//    ListInsert(&L, 4, 123);//    ListTraverse(L);    printf("\n删除操作后:");    ListDelete(&L, 4, &e);    ListTraverse(L);    return 0;}
原创粉丝点击