单链表实现
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef struct Node {
int data;
struct Node* next;
}Node;
Node* initList() { // 创建单链表
Node* L = (Node*)malloc(sizeof(Node));
L -> data = 0;
L -> next = NULL;
return L;
}
void headInsert(Node* L, int data) { //头插法
Node* node = (Node*)malloc(sizeof(Node));
node -> data = data;
node -> next = L->next;
L -> next = node;
L -> data ++;
}
void tailInsert(Node* L, int data) { //尾插法
Node* node = L;
for(int i = 0; i < L -> data; i++) {
node = node->next;
}
Node* n = (Node*)malloc(sizeof(Node));
n -> data = data;
n -> next = NULL;
node -> next = n;
L -> data ++;
}
int delete(Node* L, int data) { // 删除结点
Node* preNode = L;
Node* node = L -> next;
while(node){
if(node -> data == data) {
preNode -> next = node->next;
free(node);
L -> data --;
return TRUE;
}
preNode = node;
node = node -> next;
}
return FALSE;
}
void printList(Node* L) { // 打印链表
Node* node = L -> next;
while(node){
printf("node = %d\n", node -> data);
node = node -> next;
}
}
int main() {
Node* L = initList(); // 创建单链表
headInsert(L, 1); // 头插法
headInsert(L, 2);
headInsert(L, 3);
headInsert(L, 4);
headInsert(L, 5);
tailInsert(L, 6); // 尾插法
tailInsert(L, 7);
printList(L);
if (delete(L, 3)) {
printf("success delete\n");
}
else {
printf("fail delete\n");
}
printList(L);
return 0;
}
1.
// 使用到c++内容
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int value;
Link *next;
}Link;
/*
c++实现,其中Link *&P 在c++中可使用,C语言不可以
*/
void deleteX(Link *&p, int delNum) {//这里的第一个函数参数必须是引用值,不然会导致断链
Link *pre;//定义一个指针,进行删除
if (p == NULL){
return;
}
if (p->value == delNum) {
pre = p;
p = p->next;
free(pre);
deleteX(p, delNum);
}
else
deleteX(p->next, delNum);
}
Link *create() {
Link *p, *rear, *head;
head = (Link *)malloc(sizeof(Link));
rear = (Link *)malloc(sizeof(Link));
head = NULL;
rear = NULL;
int value;
printf("请输入链表各节点的值,以9999结束:");
scanf("%d", &value);
while (value != 9999) {//依次创建节点
p = (Link *)malloc(sizeof(Link));//创建一个新的节点
p->value = value;
p->next = NULL;
if (head == NULL) {
rear = p;
head = p;
}
else {
rear->next = p;
rear = p;
}
scanf("%d", &value);
}
rear->next = NULL;
return head;
}
Link *create2() {
Link *p, *rear, *head;
head = (Link *)malloc(sizeof(Link));
head = NULL;
int value;
printf("请输入链表各节点的值,以9999结束:");
scanf("%d", &value);
while (value != 9999) {//依次创建节点
p = (Link *)malloc(sizeof(Link));
p->value = value;
p->next = NULL;
if (head == NULL) {
head = p;
}
else {
p->next = head->next;
head->next = p;
}
scanf("%d", &value);
}
return head;
}
int main() {
int delNum;
Link *head, *q;
head = create();
q = head;
printf("打印链表:");
while (q != NULL) {
printf("%d ", q->value);
q = q->next;
}
q = head;
printf("请输入想要删除的节点的值:");
scanf("%d", &delNum);
deleteX(q, delNum);
printf("删除后链表:");
while (q != NULL) {
printf("%d ", q->value);
q = q->next;
}
return 0;
}
2.![在这里插入图片描述](https://img-blog.csdnimg.cn/ca5a854474704feebba0f4b0aaf5aa7d.png)
// 使用到c++内容
#include <stdio.h>
#include <stdlib.h>
typedef struct Link {
int data;
struct Link* next;
}Link;
/*
// c++实现,其中Link *&P 在c++中可使用,C语言不可以
void deleteX(Link*& p,int delNum) { //递归方法(c++实现)
Link* q;
if (p == NULL)
return;
if (p->data == delNum){
q = p;
p = p->next;
free(q);
deleteX(p, delNum);
}
else {
deleteX(p->next, delNum);
}
*/
//非递归,直接遍历
void deleteX(Link* p,int delNum) {
Link *pre = p, *q = p->next, *r;
while (q) {
if (q -> data == delNum) {
r = q; //r指向待删除节点
q = q->next;
pre->next = q; //删除节点
free(r); //释放节点
}
else {
pre = q;
q = q->next;
}
}
}
int main() {
//创建节点
Link *head = (Link*)malloc(sizeof(Link)); // 建立头结点
Link *q = (Link*)malloc(sizeof(Link)); // 新结点
q = head;
head->next = NULL;
int n,data,delNum;
printf("请输入结点个数:");
scanf("%d",&n);
for (int i = 0; i < n; i++) { // 尾插法
printf("请输入第%d个结点值:",i+1);
Link *p = (Link*)malloc(sizeof(Link)); // 新建结点
scanf("%d",&data);
p->data = data; // 新结点加入元素
head->next = p;
head = p;
}
head->next = NULL; //这里要将指针的next指向NULL,不然后面的判断会出问题,而且这也是应该养成的好习惯
head = q; //head回到头结点
printf("当前链表值为:");
while (head->next) {
printf("%d ",head->next->data);
head = head->next;
}
printf("\n");
printf("请输入要删除的值:");
scanf("%d",&delNum);
head = q;//head回到头结点
deleteX(head,delNum); // 删除结点
printf("删除后链表值为:");
while (head->next) {
printf("%d ", head->next->data);
head = head->next;
}
return 0;
}
3.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void reverseOutput(Link *p) {
if (p == NULL) return;
else {
reverseOutput(p->next);
printf("%d ",p->data);
}
}
int main() {
int n,data;
//创建链表
printf("请输入创建结点个数:");
scanf("%d", &n);
Link *q;
Link* head = (Link*)malloc(sizeof(Link));
head -> next = NULL;
q = head;
for(int i = 0; i < n; i++){
Link *newP = (Link *)malloc(sizeof(Link));
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
newP -> data = data;
newP -> next = NULL;
head -> next = newP;
head = head -> next; // head始终指向最新结点
}
head -> next = NULL;
head = q; // 最后head要指向头结点
reverseOutput(head->next);
return 0;
}
4.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void deleteMin(Link *p){
Link *preMinp = p, *minP = p -> next; // 记录最小值位置
Link *preq = p -> next, *q = p ->next -> next, *f;
while(q){
if(q -> data < minP -> data){
minP = q;
preMinp = preq;
}
preq = q;
q = q -> next;
}
f = minP;
preMinp -> next = minP -> next;
free(f);
}
int main() {
int n,data;
//创建链表
printf("请输入创建结点个数:");
scanf("%d", &n);
Link *q; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* head = (Link*)malloc(sizeof(Link));
head -> next = NULL;
q = head;
for(int i = 0; i < n; i++){
Link *newP = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
newP -> data = data; // 赋值给新结点
newP -> next = NULL;
head -> next = newP; // 尾插法
head = head -> next; // head始终指向最新结点
}
head -> next = NULL; // 尾插法最后置空
head = q; // 最后head要指向头结点
printf("打印链表:");
while(head -> next){
printf("%d ", head -> next -> data);
head = head -> next;
}
head = q;
deleteMin(head);
printf("\n");
printf("删除后链表值为:");
while(head -> next){
printf("%d ", head -> next -> data);
head = head -> next;
}
return 0;
}
5.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void reverse1(Link *h){ // 方法1:修改指针指向逆置
Link *pre = h, *p = h -> next, *q = h -> next, *r;
while(p){
r = p -> next;
p -> next = pre;
pre = p;
p = r;
}
h -> next = pre; // 头指针指向最后一个结点
q -> next = r; // 第一个结点指向NULL,否则为循环单链表
}
void reverse2(Link *h){ // 方法2;头插法逆置
Link *L = h, *p = h -> next, *r;
L -> next = NULL;
while(p){
r = p -> next;
p -> next = L -> next;
L -> next = p;
p = r;
}
h =L;
}
int main() {
int n,data;
//创建链表
printf("请输入创建结点个数:");
scanf("%d", &n);
Link *q; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* head = (Link*)malloc(sizeof(Link));
head -> next = NULL;
q = head;
for(int i = 0; i < n; i++){
Link *newP = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
newP -> data = data; // 赋值给新结点
newP -> next = NULL;
head -> next = newP; // 尾插法
head = head -> next; // head始终指向最新结点
}
head -> next = NULL; // 尾插法最后置空
head = q; // 最后head要指向头结点
printf("打印链表:");
while(head -> next){
printf("%d ", head -> next -> data);
head = head -> next;
}
head = q;
reverse1(head);
printf("\n");
printf("逆置后链表值为:");
while(head -> next){
printf("%d ", head -> next -> data);
head = head -> next;
}
return 0;
}
6.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void bubbleSort(Link *h) {//冒泡排序
int flag = 0;//排序标志,产生过变动就置为1
int count = 0;//记录链表长度
Link *pre=h, *p = h->next,*r;
while (p) {
count++;
p = p->next;
}
p = h->next;
for (int i = 0; i < count;i++) {
flag = 0;
while (p->next) {//开始第i+1轮冒泡
if (p->data > p->next->data) {//前者大于后者,则需要交换
r = p->next->next;//r指向下一个节点,防止断链
pre->next = p->next;
p->next->next = p;
pre = p->next;
p->next = r;
flag = 1;//有改动,flag置为1
}
else {
pre = p;
p = p->next;
}
}
if (!flag) break;//若某一轮链表未作变换,则认定已经排好序,退出循环
pre = h;//重新从头开始遍历
p = h->next;
}
}
int main() {
int n,data;
//创建链表
printf("请输入创建结点个数:");
scanf("%d", &n);
Link *q; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* head = (Link*)malloc(sizeof(Link));
head -> next = NULL;
q = head;
for(int i = 0; i < n; i++){
Link *newP = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
newP -> data = data; // 赋值给新结点
newP -> next = NULL;
head -> next = newP; // 尾插法
head = head -> next; // head始终指向最新结点
}
head -> next = NULL; // 尾插法最后置空
head = q; // 最后head要指向头结点
printf("打印链表:");
while(head -> next){
printf("%d ", head -> next -> data);
head = head -> next;
}
head = q;
bubbleSort(head);
printf("\n");
printf("排序后链表值为:");
while(head -> next){
printf("%d ", head -> next -> data);
head = head -> next;
}
return 0;
}
7.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void deleteNum(Link *h, int min, int max) {
Link *pre=h, *p = h->next,*r;
while (p) { // 符合条件,进行删除
if(p -> data > min && p -> data < max){
r = p -> next;
pre -> next = p -> next;
free(p);
p = r;
}
else{
pre = p;
p = p -> next;
}
}
}
int main() {
int n,data;
//创建链表
printf("请输入创建结点个数:");
scanf("%d", &n);
Link *q; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* head = (Link*)malloc(sizeof(Link));
head -> next = NULL;
q = head;
for(int i = 0; i < n; i++){
Link *newP = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
newP -> data = data; // 赋值给新结点
newP -> next = NULL;
head -> next = newP; // 尾插法
head = head -> next; // head始终指向最新结点
}
head -> next = NULL; // 尾插法最后置空
head = q; // 最后head要指向头结点
printf("打印链表:");
while(head -> next){
printf("%d ", head -> next -> data);
head = head -> next;
}
printf("\n");
int min, max;
printf("请输入要删除的值的范围:\n");
printf("min=");
scanf("%d", &min);
printf("max=");
scanf("%d", &max);
head = q;
deleteNum(head, min, max);
printf("删除后链表值为:");
while(head -> next){
printf("%d ", head -> next -> data);
head = head -> next;
}
return 0;
}
8.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
Link* createLink(int num) { //创建链表
int n, data;
char letter;
printf("请输入创建链表的结点个数:");
scanf("%d", &n);
Link *q;
Link *head = (Link*) malloc(sizeof(Link));
head->next = NULL;
q = head;
for (int i = 0; i < n; i++) {
Link *newP = (Link*) malloc(sizeof(Link));
num ? printf("请输入第%d个结点的值(char):",i+1): printf("请输入第%d个结点的值(int):", i + 1);
if (num==0) { // 0代表创建整数型结点
scanf("%d", &data);
newP->data = data;
}
else { // 1代表创建字符型结点
getchar();
scanf("%c", &letter);
newP->data = letter;
}
newP->next = NULL;
head->next = newP;
head = head->next;// head要始终指向最新结点
}
head->next = NULL;
head = q; //最后head要指向头结点
printf("打印链表:");
printf("\n");
while (head->next) {
if (num==0) {
printf("%d ", head->next->data);
}
else {
printf("%c", head->next->data);
}
head = head->next;
}
printf("\n");
head = q;
return head;
}
void findCommon(Link *h1, Link *h2) {
Link *p = h1->next, *q = h2->next;
int countP = 0, countQ = 0, gap;
while(p){ // 统计元素个数
countP++;
p = p->next;
}
while(q){
countQ++;
q = q->next;
}
if(countP > countQ){ // 让p指向较长链表,q指向较短链表
p = h1->next;
q = h2->next;
gap = countP - countQ;
}
else{
p = h2->next;
q = h1->next;
gap = countQ - countP;
}
while(gap--){ // 较长链表先前进gap个位置
p = p->next;
}
while(q != NULL){
if(p->data == q->data){
printf("%d ", p->data);
}
p = p->next;
q = q->next;
}
}
int main() {
Link *h1, *h2;
//Link *createLink(int);
h1 = createLink(0);
h2 = createLink(0);
findCommon(h1,h2);
return 0;
}
9.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void delete(Link *h) {
Link *pre = h, *p = h->next, *min = h->next, *minPre = h;
p = h->next;
printf("输出顺序为:");
while (h->next) {
while (p) {
if (p->data < min->data) {
minPre = pre;
min = p;
}
pre = p;
p = p->next;
}
printf("%d ",min->data);
minPre->next = min->next;
free(min);
pre = minPre = h;
p = min = h->next;
}
printf("\n");
}
int main() {
int n,data;
//创建链表
printf("请输入创建结点个数:");
scanf("%d", &n);
Link *q; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* head = (Link*)malloc(sizeof(Link));
head -> next = NULL;
q = head;
for(int i = 0; i < n; i++){
Link *newP = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
newP -> data = data; // 赋值给新结点
newP -> next = NULL;
head -> next = newP; // 尾插法
head = head -> next; // head始终指向最新结点
}
head -> next = NULL; // 尾插法最后置空
head = q; // 最后head要指向头结点
printf("打印链表:");
while(head -> next){
printf("%d ", head ->next -> data);
head = head -> next;
}
printf("\n");
head = q;
delete(head);
printf("删除后链表值为:");
while(head -> next){
printf("%d ", head -> next -> data);
head = head -> next;
}
return 0;
}
10.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void dividel(Link *lb, Link *la){
int flag = 0; // 奇偶判定
Link *l = la, *p = la->next, *rb = lb, *ra = l;
l->next = NULL; // 原链表置空
while(p){ // 尾插法
if(!flag){ // 奇元素
ra->next = p;
ra = p;
flag = 1;
}
else{ // 偶元素
rb->next = p;
rb = p;
flag = 0;
}
p = p->next;
}
ra->next = NULL;
rb->next = NULL;
}
int main() {
int n,data;
//创建链表
printf("请输入创建结点个数:");
scanf("%d", &n);
Link *q; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* head = (Link*)malloc(sizeof(Link));
head -> next = NULL;
q = head;
for(int i = 0; i < n; i++){
Link *newP = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
newP -> data = data; // 赋值给新结点
newP -> next = NULL;
head -> next = newP; // 尾插法
head = head -> next; // head始终指向最新结点
}
head -> next = NULL; // 尾插法最后置空
head = q; // 最后head要指向头结点
printf("打印链表:");
while(head->next){
printf("%d ", head ->next -> data);
head = head -> next;
}
printf("\n");
head = q;
Link *b = (Link *)malloc(sizeof(Link)); // 创建链表b
dividel(b, head);
printf("打印链表A:");
while(head->next){
printf("%d ", head ->next -> data);
head = head -> next;
}
printf("\n");
printf("打印链表B:");
while(b -> next){
printf("%d ", b -> next -> data);
b = b -> next;
}
return 0;
}
11.
12.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void deleteRep(Link *h){
Link *pre = h, *p = h->next, *r;
while(p->next){
if(p->data == p->next->data){
r = p->next;
pre->next = p->next;
free(p);
p = r;
continue;
}
pre = p;
p = p->next;
}
}
int main() {
int n,data;
//创建链表
printf("请输入创建结点个数:");
scanf("%d", &n);
Link *q; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* head = (Link*)malloc(sizeof(Link));
head -> next = NULL;
q = head;
for(int i = 0; i < n; i++){
Link *newP = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
newP -> data = data; // 赋值给新结点
newP -> next = NULL;
head -> next = newP; // 尾插法
head = head -> next; // head始终指向最新结点
}
head -> next = NULL; // 尾插法最后置空
head = q; // 最后head要指向头结点
printf("打印链表:");
while(head->next){
printf("%d ", head ->next -> data);
head = head -> next;
}
printf("\n");
head = q;
deleteRep(head);
printf("去重后链表:");
while(head->next){
printf("%d ", head ->next -> data);
head = head -> next;
}
return 0;
}
13.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void merge(Link *ha, Link *hb){
Link *l = ha, *pa = ha->next, *pb = hb->next, *ra, *rb;
l->next = NULL;
while(pa && pb){ // 头插法
if(pa->data < pb->data){
ra = pa->next;
pa->next = l->next;
l->next = pa;
pa = ra;
}
else{
rb = pb->next;
pb->next = l->next;
l->next = pb;
pb = rb;
}
}
while(pa){
ra = pa->next;
pa->next = l->next;
l->next = pa;
pa = ra;
}
while(pb){
rb = pb->next;
pb->next = l->next;
l->next = pb;
pb = rb;
}
}
int main() {
//创建链表A
int nA,dataA;
printf("请输入链表 A 创建结点个数:");
scanf("%d", &nA);
Link *qA; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* headA = (Link*)malloc(sizeof(Link));
headA -> next = NULL;
qA = headA;
for(int i = 0; i < nA; i++){
Link *newPA = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &dataA);
newPA -> data = dataA; // 赋值给新结点
newPA -> next = NULL;
headA -> next = newPA; // 尾插法
headA = headA -> next; // head始终指向最新结点
}
headA -> next = NULL; // 尾插法最后置空
headA = qA; // 最后head要指向头结点
//创建链表B
int nB,dataB;
printf("请输入链表 B 创建结点个数:");
scanf("%d", &nB);
Link *qB; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* headB = (Link*)malloc(sizeof(Link));
headB -> next = NULL;
qB = headB;
for(int i = 0; i < nB; i++){
Link *newPB = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &dataB);
newPB -> data = dataB; // 赋值给新结点
newPB -> next = NULL;
headB -> next = newPB; // 尾插法
headB = headB -> next; // head始终指向最新结点
}
headB -> next = NULL; // 尾插法最后置空
headB = qB; // 最后head要指向头结点
printf("打印链表A:");
while(headA->next){
printf("%d ", headA ->next -> data);
headA = headA -> next;
}
printf("\n");
printf("打印链表B:");
while(headB->next){
printf("%d ", headB ->next -> data);
headB = headB -> next;
}
printf("\n");
headA = qA;
headB = qB;
merge(headA, headB);
printf("归并后链表:");
while(headA->next){
printf("%d ", headA ->next -> data);
headA = headA -> next;
}
return 0;
}
14.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void linkCommon(Link *a, Link *b, Link *c ) {
Link *lc = c,*la = a->next, *lb = b->next, *rc = lc;
while (la) {
while (lb) {
if (la->data==lb->data) {//如果是公共元素
Link *p = (Link*)malloc(sizeof(Link));
p->data = la->data;
rc->next = p;//采用尾插法
rc = p;
break;
}
lb = lb->next;
}
la = la->next;
lb = b->next;
}
rc->next = NULL;//最后一个节点指针需要指向NULL。
}
int main() {
//创建链表A
int nA,dataA;
printf("请输入链表 A 创建结点个数:");
scanf("%d", &nA);
Link *qA; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* headA = (Link*)malloc(sizeof(Link));
headA -> next = NULL;
qA = headA;
for(int i = 0; i < nA; i++){
Link *newPA = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &dataA);
newPA -> data = dataA; // 赋值给新结点
newPA -> next = NULL;
headA -> next = newPA; // 尾插法
headA = headA -> next; // head始终指向最新结点
}
headA -> next = NULL; // 尾插法最后置空
headA = qA; // 最后head要指向头结点
//创建链表B
int nB,dataB;
printf("请输入链表 B 创建结点个数:");
scanf("%d", &nB);
Link *qB; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* headB = (Link*)malloc(sizeof(Link));
headB -> next = NULL;
qB = headB;
for(int i = 0; i < nB; i++){
Link *newPB = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &dataB);
newPB -> data = dataB; // 赋值给新结点
newPB -> next = NULL;
headB -> next = newPB; // 尾插法
headB = headB -> next; // head始终指向最新结点
}
headB -> next = NULL; // 尾插法最后置空
headB = qB; // 最后head要指向头结点
//创建链表C
Link *c = (Link*)malloc(sizeof(Link));
c->next = NULL;
printf("打印链表A:");
while(headA->next){
printf("%d ", headA ->next -> data);
headA = headA -> next;
}
printf("\n");
printf("打印链表B:");
while(headB->next){
printf("%d ", headB ->next -> data);
headB = headB -> next;
}
printf("\n");
headA = qA;
headB = qB;
linkCommon(headA, headB, c);
printf("C链表为:");
while(c->next){
printf("%d ", c ->next -> data);
c = c -> next;
}
return 0;
}
15.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void listCommon(Link *a, Link *b) {
Link *pa = a->next, *pb = b->next, *r, *la = a;
la->next = NULL;
while (pa && pb) {
if (pa->data == pb->data) {//如果是公共元素
la->next = pa; // 尾插法
la = pa;
pa = pa->next;
pb = pb->next;
}
else{
if(pa->data < pb->data){
pa = pa->next;
}
else{
pb = pb->next;
}
}
}
la->next = NULL;//最后一个节点指针需要指向NULL。
}
int main() {
//创建链表A
int nA,dataA;
printf("请输入链表 A 创建结点个数:");
scanf("%d", &nA);
Link *qA; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* headA = (Link*)malloc(sizeof(Link));
headA -> next = NULL;
qA = headA;
for(int i = 0; i < nA; i++){
Link *newPA = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &dataA);
newPA -> data = dataA; // 赋值给新结点
newPA -> next = NULL;
headA -> next = newPA; // 尾插法
headA = headA -> next; // head始终指向最新结点
}
headA -> next = NULL; // 尾插法最后置空
headA = qA; // 最后head要指向头结点
//创建链表B
int nB,dataB;
printf("请输入链表 B 创建结点个数:");
scanf("%d", &nB);
Link *qB; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* headB = (Link*)malloc(sizeof(Link));
headB -> next = NULL;
qB = headB;
for(int i = 0; i < nB; i++){
Link *newPB = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &dataB);
newPB -> data = dataB; // 赋值给新结点
newPB -> next = NULL;
headB -> next = newPB; // 尾插法
headB = headB -> next; // head始终指向最新结点
}
headB -> next = NULL; // 尾插法最后置空
headB = qB; // 最后head要指向头结点
printf("打印链表A:");
while(headA->next){
printf("%d ", headA ->next -> data);
headA = headA -> next;
}
printf("\n");
printf("打印链表B:");
while(headB->next){
printf("%d ", headB ->next -> data);
headB = headB -> next;
}
printf("\n");
headA = qA;
headB = qB;
listCommon(headA, headB);
printf("合并后链表为:");
while(headA->next){
printf("%d ", headA ->next -> data);
headA = headA -> next;
}
return 0;
}
16.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
void subList(Link *a, Link *b) {
Link *pa = a->next, *pb = b->next, *r, *la = a;
while (pa && pb) {
if (pa->data == pb->data) {//如果是公共元素
pa = pa->next;
pb = pb->next;
}
else{
pb = b->next;
la = la->next;
pa = la->next;
}
}
if(pb == NULL){
printf("True"); // 链表B是链表A的子列
}
else{
printf("False"); // 链表B不是链表A的子列
}
}
int main() {
//创建链表A
int nA,dataA;
printf("请输入链表 A 创建结点个数:");
scanf("%d", &nA);
Link *qA; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* headA = (Link*)malloc(sizeof(Link));
headA -> next = NULL;
qA = headA;
for(int i = 0; i < nA; i++){
Link *newPA = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &dataA);
newPA -> data = dataA; // 赋值给新结点
newPA -> next = NULL;
headA -> next = newPA; // 尾插法
headA = headA -> next; // head始终指向最新结点
}
headA -> next = NULL; // 尾插法最后置空
headA = qA; // 最后head要指向头结点
//创建链表B
int nB,dataB;
printf("请输入链表 B 创建结点个数:");
scanf("%d", &nB);
Link *qB; // 工作指针,记录头结点位置,最后head需要指向头结点
Link* headB = (Link*)malloc(sizeof(Link));
headB -> next = NULL;
qB = headB;
for(int i = 0; i < nB; i++){
Link *newPB = (Link *)malloc(sizeof(Link)); // 创建新结点
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &dataB);
newPB -> data = dataB; // 赋值给新结点
newPB -> next = NULL;
headB -> next = newPB; // 尾插法
headB = headB -> next; // head始终指向最新结点
}
headB -> next = NULL; // 尾插法最后置空
headB = qB; // 最后head要指向头结点
printf("打印链表A:");
while(headA->next){
printf("%d ", headA ->next -> data);
headA = headA -> next;
}
printf("\n");
printf("打印链表B:");
while(headB->next){
printf("%d ", headB ->next -> data);
headB = headB -> next;
}
printf("\n");
headA = qA;
headB = qB;
subList(headA, headB);
return 0;
}
17.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *pre;
struct Link *next;
}Link;
Link *createDoubleLoopLink() {
int n, data;
Link *head = (Link*)malloc(sizeof(Link));
head->next = NULL;
head->pre = NULL;
Link *p = head;
printf("请输入结点个数:");
scanf("%d", &n);
for(int i = 0; i < n; i++){
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
Link *newP = (Link*)malloc(sizeof(Link));
newP->data = data;
newP->pre = p;
p->next = newP;
p = newP;
}
p->next = head;
head->pre = p;
return head;
}
Link *isSymmetry(Link *h){
Link *pre = h->pre, *next = h->next;
while(pre != next && pre->pre != next){
if(pre->data != next->data){
printf("该双链表不对称");
break;
}
else{
pre = pre->pre;
next = next->next;
}
}
if(pre == next || pre->pre == next){
printf("该双链表对称");
}
}
int main() {
Link *head;
Link *createDoubleLoopLink();
head = createDoubleLoopLink();
isSymmetry(head);
return 0;
}
18.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
Link *createSinLoopLink() { // 创建循环单链表
int n, data;
Link *head = (Link*)malloc(sizeof(Link));
head->next = NULL;
Link *p = head;
printf("请输入结点个数:");
scanf("%d", &n);
for(int i = 0; i < n; i++){
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
Link *newP = (Link*)malloc(sizeof(Link));
newP->data = data;
p->next = newP;
p = newP;
}
p->next = head;
return head;
}
void linkTwoLists(Link *h1, Link *h2){
Link *p1 = h1->next, *p2 = h2->next;
while(p1->next != h1){ // 判断p1->next是否等于h1,进而判断是否到达尾结点
p1 = p1->next;
}
p1->next = p2;
while(p2->next != h2){
p2 = p2->next;
}
p2->next = h1;
free(h2);
}
int main() {
Link *h1, *h2, *p;
Link *createSinLoopLink();
h1 = createSinLoopLink();
h2 = createSinLoopLink();
linkTwoLists(h1, h2);
p = h1->next;
printf("新循环链表为:");
while(p != h1){
printf("%d ", p->data);
p = p->next;
}
return 0;
}
19.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
Link *createSinLoopLink() { // 创建循环单链表
int n, data;
Link *head = (Link*)malloc(sizeof(Link));
head->next = NULL;
Link *p = head;
printf("请输入结点个数:");
scanf("%d", &n);
for(int i = 0; i < n; i++){
printf("请输入第%d个结点的值:", i + 1);
scanf("%d", &data);
Link *newP = (Link*)malloc(sizeof(Link));
newP->data = data;
p->next = newP;
p = newP;
}
p->next = head;
return head;
}
void DeleteLink(Link *h){
Link *pre = h, *minpre = h, *p = h->next, *min = h->next, *r;
while(h->next != h){
while(p != h){ // 寻找最小值
if(min->data > p->data){
minpre = pre;
min = p;
}
pre = p;
p = p->next;
}
printf("%d ", min->data);
r = min->next;
minpre->next = min->next; // 删除当前最小值
free(min);
p = h->next; // 重新遍历
pre = h;
minpre = h;
min = h->next;
}
free(h); // 释放头结点
}
int main() {
Link *head;
Link *createSinLoopLink();
head = createSinLoopLink();
DeleteLink(head);
return 0;
}
20.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
int freq;
struct Link *next;
struct Link *pre;
}Link;
void locate(Link *h,int num) {
int flag = 0; //找到标志
Link *pre = h, *p = h->next, *t, *preQ = h, *q;
while (p) {
if (p->data==num) {//如果找到
flag = 1;//表示找到
p->freq++;
t = p; //保存该结点
if (p->next) {
pre->next = p->next;//取出该结点
p->next->pre = pre;
}
else {
pre->next = NULL;//如果我们查找的结点是最后一个结点,我们要将next指向NULL,不然之后遍历时会出问题
}
q = h->next;
while (q) {//进行排序
if (t->freq >= q->freq) {//结点freq大于等于当前遍历结点时,插入
t->next = q;
q->pre = t;
preQ->next = t;
t->pre = preQ;
break;
}
preQ = q;
q = q->next;
}
break;
}
pre = p;
p = p->next;
}
if (!flag) {
printf("未找到该元素,序列不改变");
}
}
int main() {
// 创建双链表
int n, data,num;
Link *head = ( Link *)malloc(sizeof(Link));
head->next = NULL;
head->pre = NULL;
Link *p = head;
printf("请输入节点个数:n=");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
printf("请输入第%d个节点值:", i + 1);
scanf("%d", &data);
Link *newP = ( Link*)malloc(sizeof( Link));
newP->data = data;
newP->pre = p;
newP->freq = 0;
p->next = newP;
p = newP;
}
p->next = NULL;
do {
printf("\n");
printf("请输入要查找的值,输入9999代表结束:num=");
scanf("%d",&num);
if (num == 9999)continue;//如果num=9999,跳入下一次循环
locate(head,num);
p = head->next;
printf("调整后链表为:");
while (p) {
printf("%d ",p->data);
p = p->next;
}
} while (num!=9999);
return 0;
}
21.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
Link* createLink(int num) { //创建链表
int n, data;
char letter;
printf("请输入创建链表的结点个数:");
scanf("%d", &n);
Link *q;
Link *head = (Link*) malloc(sizeof(Link));
head->next = NULL;
q = head;
for (int i = 0; i < n; i++) {
Link *newP = (Link*) malloc(sizeof(Link));
num ? printf("请输入第%d个结点的值(char):",i+1): printf("请输入第%d个结点的值(int):", i + 1);
if (num==0) { // 0代表创建整数型结点
scanf("%d", &data);
newP->data = data;
}
else { // 1代表创建字符型结点
getchar();
scanf("%c", &letter);
newP->data = letter;
}
newP->next = NULL;
head->next = newP;
head = head->next;// head要始终指向最新结点
}
head->next = NULL;
head = q; //最后head要指向头结点
printf("打印链表:");
printf("\n");
while (head->next) {
if (num==0) {
printf("%d ", head->next->data);
}
else {
printf("%c", head->next->data);
}
head = head->next;
}
printf("\n");
head = q;
return head;
}
Link *isLoop(Link *h) {
Link *fast = h, *slow = h;
while(slow && fast && fast->next){ // slow每次走一步,fast每次走两步
slow = slow->next;
fast = fast->next->next;
if(slow == fast){ // 再次相遇,有环
break;
}
}
if(slow == NULL || (fast == NULL || fast->next == NULL)){ // 无环
return NULL;
}
fast = h;
while(fast != slow){
fast = fast->next;
slow = slow->next;
}
return fast;
}
int main() {
Link *head,*l, *s;
int count = 0; //默许创建的链表中结点的绝对值<=100
//Link *createLink(int);
head = createLink(0);
l = head;
while(l->next){
l = l->next;
}
l->next = head->next->next->next; // 手动设置一个环
s = isLoop(head);
if(s){
printf("链表环起始结点值为:%d", s->data);
}
else{
printf("链表无环");
}
return 0;
}
22.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
Link* createSinLink(int num) { //创建链表
int n, data;
char letter;
printf("请输入创建链表的结点个数:");
scanf("%d", &n);
Link *q;
Link *head = (Link*) malloc(sizeof(Link));
head->next = NULL;
q = head;
for (int i = 0; i < n; i++) {
Link *newP = (Link*) malloc(sizeof(Link));
num ? printf("请输入第%d个结点的值(char):",i+1): printf("请输入第%d个结点的值(int):", i + 1);
if (num==0) { // 0代表创建整数型结点
scanf("%d", &data);
newP->data = data;
}
else { // 1代表创建字符型结点
getchar();
scanf("%c", &letter);
newP->data = letter;
}
newP->next = NULL;
head->next = newP;
head = head->next;// head要始终指向最新结点
}
head->next = NULL;
head = q; //最后head要指向头结点
printf("打印链表:");
printf("\n");
while (head->next) {
if (num==0) {
printf("%d ", head->next->data);
}
else {
printf("%c", head->next->data);
}
head = head->next;
}
printf("\n");
head = q;
return head;
}
void findTheReciprocalK1(Link *h, int k){ // 方法1
Link *p = h->next;
int count = 0, num;
while(p){ // 统计元素个数
count++;
p = p->next;
}
p = h->next;
if(k > count){
return 0;
}
else{
num = count - k + 1;
while(--num){
p = p->next;
}
printf("%d ", p->data);
return 1;
}
}
void findTheReciprocalK2(Link *h, int k){ // 方法2
Link *p = h->next, *q = h->next;
int count = k;
while(count--){ // 先让q走k个位置
if(q == NULL){
printf("倒数第%d个结点不存在", k);
return 0;
}
q = q->next;
}
while(q != NULL){ // p, q同时后移,当q为空时,p所指为倒数第k个元素
p = p->next;
q = q->next;
}
printf("倒数第%d个结点值为:%d", k, p->data);
return 1;
}
int main() {
int k;
Link *head;
//Link *createSinLink();
head = createSinLink(0);
printf("请输入需查找倒数第几个数:");
scanf("%d", &k);
//findTheReciprocalK1(head, k);
findTheReciprocalK2(head, k);
return 0;
}
23.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
union{
int data;
char letter;
};
struct Link *next;
}Link;
Link* createLink(int num) { //创建链表
int n, data;
char letter;
printf("请输入创建链表的结点个数:");
scanf("%d", &n);
Link *q;
Link *head = (Link*) malloc(sizeof(Link));
head->next = NULL;
q = head;
for (int i = 0; i < n; i++) {
Link *newP = (Link*) malloc(sizeof(Link));
num ? printf("请输入第%d个结点的值(char):",i+1): printf("请输入第%d个结点的值(int):", i + 1);
if (num == 0) { // 0代表创建整数型结点
scanf("%d", &data);
newP->data = data;
}
else { // 1代表创建字符型结点
getchar();
scanf("%c", &letter);
newP->data = letter;
}
newP->next = NULL;
head->next = newP;
head = head->next; // head要始终指向最新结点
}
head->next = NULL;
head = q; //最后head要指向头结点
printf("打印链表:");
printf("\n");
while (head->next) {
if (num==0) {
printf("%d ", head->next->data);
}
else {
printf("%c", head->next->data);
}
head = head->next;
}
printf("\n");
head = q;
return head;
}
Link *findCommonSuffix(Link *h1,Link *h2){
Link *p = h1->next, *q = h2->next;
int countP = 0, countQ = 0, gap;
while(p){ // 获取链表长度
countP++;
p = p->next;
}
while(q){
countQ++;
q = q->next;
}
if(countQ > countP){ // 让p指针始终指向较长的链表
p = h2->next;
q = h1->next;
gap = countQ - countP;
}
else{
p = h1->next;
q = h2->next;
gap = countP - countQ;
}
while(gap--){ // 较长链表先走gap个位置
p = p->next;
}
while(q != p && q != NULL){ // 当指针不同且不为空时继续向后移动
q = q->next;
p = p->next;
}
return p;
}
int main() {
Link *h1, *h2, *com, *p1, *p2, *start;
//Link *createLink(int);
char p[] = "letter";
h1 = createLink(1);
h2 = createLink(1);
com = createLink(1); // 公共部分
p1 = h1->next;
p2 = h2->next;
while(p1->next){ // 到达链尾
p1 = p1->next;
}
while(p2->next){
p2 = p2->next;
}
p1->next = com->next; // 链接公共部分
p2->next = com->next;
p1 = h1->next;
p2 = h2->next;
while(p1){
printf("%c ", p1->letter);
p1 = p1->next;
}
printf("\n");
while(p2){
printf("%c ", p2->letter);
p2 = p2->next;
}
printf("\n");
start = findCommonSuffix(h1, h2);
printf("%c ", start->letter);
return 0;
}
24.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
union{
int data;
}type;
int data;
struct Link *next;
}Link;
Link* createLink(int num) { //创建链表
int n, data;
char letter;
printf("请输入创建链表的结点个数:");
scanf("%d", &n);
Link *q;
Link *head = (Link*) malloc(sizeof(Link));
head->next = NULL;
q = head;
for (int i = 0; i < n; i++) {
Link *newP = (Link*) malloc(sizeof(Link));
num ? printf("请输入第%d个结点的值(char):",i+1): printf("请输入第%d个结点的值(int):", i + 1);
if (num==0) { // 0代表创建整数型结点
scanf("%d", &data);
newP->data = data;
}
else { // 1代表创建字符型结点
getchar();
scanf("%c", &letter);
newP->data = letter;
}
newP->next = NULL;
head->next = newP;
head = head->next;// head要始终指向最新结点
}
head->next = NULL;
head = q; //最后head要指向头结点
printf("打印链表:");
printf("\n");
while (head->next) {
if (num==0) {
printf("%d ", head->next->data);
}
else {
printf("%c", head->next->data);
}
head = head->next;
}
printf("\n");
head = q;
return head;
}
void deleteRepAbs(Link *h,int n) {
int *arr = (int *)malloc(sizeof(int)*n);//大小是sizeof(int)*n
for (int i = 0; i < n;i++) { //赋初值0
*(arr + i) = 0;
}
Link *pre = h, *p = h->next, *r;
while (p) {
if (*(arr+abs(p->data))==0) {//首次访问
*(arr + abs(p->data)) = 1;
pre = p;
p = p->next;
}
else {
r = p->next;
pre->next = p->next; //删除
free(p);
p = r;
}
}
}
int main() {
Link *head,*p;
int n = 100; //默许创建的链表中结点的绝对值<=100
//Link *createLink(int);
head = createLink(0);
deleteRepAbs(head,n);
p = head->next;
printf("去重后链表为:");
while (p) {
printf("%d ", p->data);
p = p->next;
}
return 0;
}
25.
#include <stdio.h>
#include <stdlib.h>
typedef struct Link
{
int data;
struct Link *next;
}Link;
Link* createLink(int num) { //创建链表
int n, data;
char letter;
printf("请输入创建链表的结点个数:");
scanf("%d", &n);
Link *q;
Link *head = (Link*) malloc(sizeof(Link));
head->next = NULL;
q = head;
for (int i = 0; i < n; i++) {
Link *newP = (Link*) malloc(sizeof(Link));
num ? printf("请输入第%d个结点的值(char):",i+1): printf("请输入第%d个结点的值(int):", i + 1);
if (num==0) { // 0代表创建整数型结点
scanf("%d", &data);
newP->data = data;
}
else { // 1代表创建字符型结点
getchar();
scanf("%c", &letter);
newP->data = letter;
}
newP->next = NULL;
head->next = newP;
head = head->next;// head要始终指向最新结点
}
head->next = NULL;
head = q; //最后head要指向头结点
printf("打印链表:");
printf("\n");
while (head->next) {
if (num==0) {
printf("%d ", head->next->data);
}
else {
printf("%c", head->next->data);
}
head = head->next;
}
printf("\n");
head = q;
return head;
}
void crossLink(Link *h) {
void reverse(Link *);
Link *fast = h->next, *slow = h->next, *mid;
mid = (Link *)malloc(sizeof(Link));
while(fast->next && fast->next->next){ // 寻找中间结点
slow = slow->next;
fast = fast->next->next;
}
mid->next = slow->next;
reverse(mid); // 逆置mid后的结点
slow->next = mid->next;
fast = h->next;
slow->next = NULL;
slow = mid->next;
while(slow){ // 逐个进行输入
mid = slow->next;
slow->next = fast->next;
fast->next = slow;
slow = mid;
fast = fast->next->next;
}
}
void reverse(Link *h){ //头插法逆置
Link *p = h->next, *r;
h->next = NULL;
while(p){
r = p->next;
p->next = h->next;
h->next = p;
p = r;
}
}
int main() {
Link *head,*p;
int count = 0; //默许创建的链表中结点的绝对值<=100
//Link *createLink(int);
head = createLink(0);
crossLink(head);
printf("新链表为:");
p = head->next;
while(p){
printf("%d ", p->data);
p = p->next;
}
return 0;
}