单链表编程考点
1、将单链表的第一个结点放在单链表的最后一个结点的后面
/*
设h是无头结点的单链表,如果线性表h的长度不小于2,则将首元结点删除并插入到表尾
将单链表的第一个结点放在单链表的最后一个结点的后面
*/
typedef struct node
{elementype data;struct node *next;
}*linklist;void change(linklist &h) //linklist &h等价于struct node *&h,这样就可以修改指针h的值;此时不需要return返回已经修改的单链表的值
{linklist p,q; //linklist p,q等价于struct node *p、struct node *q;if(h && h->next) //如果链表中有不少于2个结点{q = h; //令p指向第1个结点hh = h->next; //令h指向第2个结点p = h; //令p指向第2个结点while(p->next) //第一次循环时,判断第2个结点的指针域是否为空,如果为空则只有两个结点,则不需要找到最后的一个结点,否则一直循环,找到最后一个结点为止p = p->next; //顺着p开始往下找,一直找到最后一个结点p->next = q; //将第一个结点接在最后一个结点后面q->next = NULL; //新的尾结点没有后继,置后继为空}
}
/*分析:1、在if判断语句中h为单链表的某一指针指向单链表中的某一个结点2、q = h;此语句的含义是另外一个指针q与指针h同时指向同一个结点3、h = h->next;此语句中的h->next所表示的含义是h->next指向单链表中h指针指向的下一个结点,与此同时h指针和h->next指针同时指向该结点
*/
typedef struct node
{elementype data;struct node *next;
}*Linklist;Linklist mynode(LinkList L) //L是不带头结点的单链表的头指针
{if(L && L->next) //如果链表中有不少于2个结点{q = L; //令p指向第1个结点hL = L->next; //令h指向第2个结点p = L; //令p指向第2个结点while(p->next)p = p->next; //顺着p开始往下找,一直找到最后一个结点p->next = q; //将第一个结点接在最后一个结点后面q->next = NULL; //新的尾结点没有后继,置后继为空}return L;
}
2、实现单链表的删除算法,删除成功返回1,删除失败返回0
/*实现单链表的删除算法,删除成功返回1,删除失败返回0*/
typedef struct node
{elementype data;struct node *next;
}*LinkList, LNode;int ListDelete(LinkList L, int i, ElemType *s) //s是存储将要删除的值,i是将要被删除元素的指定位置
{LNode *p,*q; //定义了两个新的指针变量p、q;int j;p = L; //p指向L单链表的第一个结点元素j = 0;while((p->next != NULL)&&(j < i-1)) //j < i-1此处的判断条件是i-1的原因是当最后一次,不满足条件之前,j的值自动增加了一位{p = p->next; //而我们进行删除操作的前提是找到被删除结点元素的前驱结点j++; }if(p->next == NULL || j > i-1)return 0; //如果if语句成立,将执行return 0;语句,运行过程终止q=p->next; //否则将q指针指向p->next指针所指的结点,即指向被删除结点元素 *s = q->data;p->next = q->next; //此语句将指定位置的结点删除,p->next所代表的是被删结点元素的前驱结点的next指针域,而q->next指向被删结点元素的后继结点free(q); //释放结点占有的存储空间return 1;
}
3、尾插法建立单链表
//尾插法建立单链表
typedef struct node
{int data;struct node *next;
}lklist;
void lklistcreate(lklist *&head ,int n) //n表示单链表的长度
{lklist *q; //定义一个新的结点指针 for(i = 1;i<=n;i++){ p=(lklist *)malloc(sizeof(lklist)); //创建一个新的结点scanf("%d",&(p->data)); //获取该结点的数值p->next = NULL;if(i==1)head = q = p; //head = q = p;该语句表示头指针head,新的结点指针q都指向结点p;else{q->next = p; //注意:定义的新的结点指针q的作用是通过移动该指针的指向,来实现链表的创建,将q结点的next指针域指向最新创建的结点q=p; //将结点连接以后,再改变q指针的指向,为下一次新结点的创建作好准备}}
}
4、逆转线性单链表,采用是头插法
//逆转线性单链表,采用是头插法
typedef struct node //就地逆置单链表
{elemtype data;struct node *next;
}node;
node *Reverse (node *head) //head是带头结点的单链表
{node *p ,*q;p = head->next; //p指向第一个元素head->next=NULL; //保留第一个元素,将头结点的指针域置空while(p!=NULL) //将原链表的元素用头插法插入新的链表中{q=p; //令q指向链表的当前第一个元素p=p->next; //p指针后移q->next = head->next; //在新表中插入结点qhead->next = q;}return head;
}
5、在带头结点的单链表L中,删除所有值为x的结点
//在带头结点的单链表L中,删除所有值为x的结点
typedef struct LNode
{Elemtype data;struct LNode *next;
}LNode, *Linklist;
void delete(Linklist &L ,ElemType x)
{LNode *q=L;LNode p=L->next; //初始化p指向第一个结点,q始终指向p结点的前驱while(p!=NULL){if(p->data == x) //若p指针指向当前结点的值等于x{q->next = p->next;free(p); //删除该结点,并修改p指针p=q->next; //寻找链表中下一个值为x的结点}else{q=p;p=p->next; //先使q后移,p向后移动}}
}
6、有序递增序列,删除所有值大于mink且小于maxk的元素
//有序递增序列,删除所有值大于mink且小于maxk的元素
typedef struct node //就地逆置单链表
{elemtype data;struct node *next;
}node;
void Delete_Between(node *head, int mink, int maxk)
{node *p = head, *q;while(p->next->data <= mink) //p是最后一个不大于mink的元素p=p->next;if(p->next) //如果还有比mink更大的元素{q=p->next;while(q->data<maxk) //q是第一个不小于maxk的元素q=q->next; //while循环结束以后,q指向比maxk值还大的结点元素p->next = q; //此语句是删除所有值大于mink且小于maxk的元素 }
}
7、将带头结点单链表h1和h2合并成升序排列的单链表
//将带头结点单链表h1和h2合并成升序排列的单链表
typedef struct L
{int data;struct L *next;
}LinkL;
LinkL *mergeList(LinkL *h1, LinkL *h2)
{LinkL *h, *Next, *q;h=h1;Next = h;h1=h1->next; //表h1的第一个结点h2=h2->next; //表h2的第一个结点while(h1 != NULL && h2 != NULL) //如果表h1和h2均不为空表{if(h1->data <= h2->data) //如果h1指针所指向当前结点的值小于h2{ //指针所指向的当前结点的值q=h1; //则令q暂存h1指针所指向的结点h1=h1->next; //h1指针向后移动}else //如果h2指针所指向当前结点的值小于h1{ //指针所指向的当前结点的值q=h2; //则令q暂存h2指针所指向的结点h2-h2->next; //h2指针向后移动}Next->next = q; //将指针p所指向的结点接在Next指针所指的结点后面Next = q; }if(h1 == NULL) //如果原h2链表中所有结点已插入但是原h1链表还有结点没插完,则直接把剩余部分接在next指针后面。要是原h1表的所有结点已经全部插完但是h2还有结点没插完,亦是如此Next->next = h2;if(h2 == NULL)Next->next = h1;return h; //返回新表的指针}
8、用单链表lc表示集合C,分别将la中的元素取出,再在lb中进行查找,如果在lb中出现,则将其插入到lc中
//将单链表A分解成一个小于零的单链表和大于零的单链表
typedef struct node
{elemtype data;struct node *next;
}*LinkList,Linknode;
void decompose(LinkList La,LinkList Lb,LinkList Lc)
{Linknode *p; Lc=(Linknode *)malloc(sizeof(Linknode)); Lc->next = NULL; //表C的头结点的next域置空p=La->next; //令p指向表A的第一个元素结点Lb=La; //令Lb指向表LaLb->next = NULL; //令表La的next域置空while(p) //遍历原表A{La=p->next; //令La暂存p结点的后继指针if(p->data >0) //如果p结点值大于0,则接在表C后面{p->next=Lc->next;Lc->next = p;}else{ //如果p结点的值小于0,则接在表B后面p->next =Lb->next;Lb->next = p;}p=La; //令p指向原p所指向的结点的下一个位置}
}
9、将单链表A分解成一个小于零的单链表和大于零的单链表
//用单链表lc表示集合C,分别将la中的元素取出,再在lb中进行查找,如果在lb中出现,则将其插入到lc中
typedef struct node
{elemtype data;struct node *next;
}*LinkList,LNode;
void interaction(LinkList la, LinkList lb, LinkList &lc)
{LinkList pa ,pb, pc;lc = new LNode(); //生成lc的头结点pc=lc; //pc永远指向lc的尾结点pa=la->next; //pa指向la的第一个元素while(pa){pb=lb->next; //pa指向lb表的第一个元素while(pb && pb->data != pa->data)pb=pb->next; //在pb中查找元素,使其值等于pa->dataif(pb) //如果存在这样的元素{pc->next = new LNode(); //生成lc新的尾结点pc = pc->next; //pc指向新的尾结点pc->data= pa->data; //将pa->data复制到pc中}pa=pa->next; //继续比较pa表的下一个结点元素}pc->next =NULL; //pc为尾结点,pc表比较完成后,置pc后继为空
}
10、已知指针hb和ha分别指向两个单链表的头结点,长度为m和n,假设hc指向连接后的链表的头结点
//已知指针hb和ha分别指向两个单链表的头结点,长度为m和n,假设hc指向连接后的链表的头结点
typedef struct node
{elemtype data;struct node *next;
}LinkList;
void ListConcat(LinkList ha, LinkList hb, LinkList *hc)
{ LinkList p; //把链表hb接在ha后面形成链表hchc=ha; //由指针p指向ha的尾元结点while(p->next !=NULL) //查找原ha表的最后一个结点p=p->next;p->next = hb->next; //把hb表的第一个元素及其后面元素接在p指针指向的结点后面free(hb);
}
11、删除单链表中重复的元素
//删除单链表中重复的元素
typedef struct node
{elemtype data;struct node *next;
}LinkedList ,*LNode;
LinkedList DeleteSameElement(LinkedList L)
{ //L为递增有序的单链表LNode u;LinkedList p, pre;pre = L->next; //pre指针指向第一个元素结点p= pre->next; //p指向pre所指结点的后继结点while(p!=NULL) //如果p指针不为空if(p->data == pre->data) //p所指结点的值等于pre所指结点的值{u=p; //用指针u暂存p指针所指向的结点p=p->next; //p指针后移free(u); //释放掉u指针所值结点的内存空间}else{ //p和pre两指针所指向的结点值不相等pre = p; //pre指针后移p = p->next; //p指针后移}
}
12、交换单链表中指针p所指结点与其后继结点
//交换单链表中指针p所指结点与其后继结点
typedef struct node
{elemtype data;struct node *next;
}*LinkList;
int exchange(Linklist &head,Linklist p )
{LinkList q=head->next; //q指向第一个元素结点LinkList pre=head; //pre指向头结点while(q!=NULL && q!=p) //顺着链表开始查找,一直到q=p{pre=q;q=q->next;}if(p->next ==NULL) //退出循环之后,若p无后继,则交换失败return 0;else{q=p->next;pre->next = q;p->next = q->next;q->next = p;}return 1;
}
13、设有一个无序单链表
1)找出最小值结点
2)若该数是奇数将与其直接后继结点的数值交换
3)该数值是偶数将直接后继结点删除
/*
设有一个无序单链表
1、找出最小值结点
2、若该数是奇数将与其直接后继结点的数值交换
3、该数值是偶数将直接后继结点删除
*/
typedef struct node
{elemtype data;struct node *next;
}LinkList;
void OutputMin(LinkList L)
{int temp;LinkList q = L->next; //p指向第一个元素结点LinkList p= q;while(q){ //找出最小值结点p,并打印p结点数值if(p->data >q->data)p=q; //如果发现还有比p指针所指结点的值更小的结点,令p指向该结点,否则q后移q=q->next;}printf("%d",p->data);if(p->next != NULL) //找到了值最小的结点,若该结点有后继结点{if(p->data % 2 == 1) //如果该最小值是奇数,则与其后继结点交换{temp=p->data;p->data =p->next->data;p->next->data = temp;}else //如果该最小值是偶数,则删除其后继结点{q=p->next;p->next = q->next;free(q);}}
}